From a2946f86014aa98ba7f953bbbe60629b769859fe Mon Sep 17 00:00:00 2001 From: Rebeka Dekany <50901361+rebekadekany@users.noreply.github.com> Date: Wed, 1 Nov 2023 14:33:25 +0100 Subject: [PATCH] Merge pull request #15249 from overleaf/rd-odc-radio Radio buttons for Onboarding Data Collection GitOrigin-RevId: 8c4d1e965f3263b4c8a41c129c5c3d6e3ef10986 --- .../web/frontend/extracted-translations.json | 7 +++ .../js/shared/components/radio-chip.tsx | 42 ++++++++++++++ .../frontend/stories/radio-chip.stories.tsx | 23 ++++++++ .../frontend/stylesheets/_style_includes.less | 1 + .../stylesheets/components/radio-chip.less | 57 +++++++++++++++++++ .../web/frontend/stylesheets/main-style.less | 1 + .../modules/overleaf-integration.less | 15 ++++- services/web/locales/en.json | 7 +++ .../shared/components/radio-chip.test.tsx | 57 +++++++++++++++++++ 9 files changed, 207 insertions(+), 3 deletions(-) create mode 100644 services/web/frontend/js/shared/components/radio-chip.tsx create mode 100644 services/web/frontend/stories/radio-chip.stories.tsx create mode 100644 services/web/frontend/stylesheets/components/radio-chip.less create mode 100644 services/web/test/frontend/shared/components/radio-chip.test.tsx diff --git a/services/web/frontend/extracted-translations.json b/services/web/frontend/extracted-translations.json index 44316b2797..f06fc298b6 100644 --- a/services/web/frontend/extracted-translations.json +++ b/services/web/frontend/extracted-translations.json @@ -457,6 +457,7 @@ "headers": "", "help": "", "help_improve_overleaf_fill_out_this_survey": "", + "helps_us_tailor_your_experience": "", "hide_configuration": "", "hide_document_preamble": "", "hide_outline": "", @@ -839,6 +840,12 @@ "premium_plan_label": "", "press_shortcut_to_open_advanced_reference_search": "", "price": "", + "primarily_work_study_question": "", + "primarily_work_study_question_government": "", + "primarily_work_study_question_nonprofit_ngo": "", + "primarily_work_study_question_other": "", + "primarily_work_study_question_private_company": "", + "primarily_work_study_question_university_school": "", "priority_support": "", "private": "", "problem_talking_to_publishing_service": "", diff --git a/services/web/frontend/js/shared/components/radio-chip.tsx b/services/web/frontend/js/shared/components/radio-chip.tsx new file mode 100644 index 0000000000..0909f11aa0 --- /dev/null +++ b/services/web/frontend/js/shared/components/radio-chip.tsx @@ -0,0 +1,42 @@ +import React from 'react' + +type RadioChipProps = { + checked?: boolean + disabled?: boolean + name: string + onChange: (value: ValueType) => void + required?: boolean + label: React.ReactElement | string + value: ValueType +} + +const RadioChip = ({ + checked, + disabled, + name, + onChange, + label, + required, + value, +}: RadioChipProps) => { + const handleChange = () => { + onChange(value) + } + + return ( + + ) +} + +export default RadioChip diff --git a/services/web/frontend/stories/radio-chip.stories.tsx b/services/web/frontend/stories/radio-chip.stories.tsx new file mode 100644 index 0000000000..f1d118f980 --- /dev/null +++ b/services/web/frontend/stories/radio-chip.stories.tsx @@ -0,0 +1,23 @@ +import RadioChip from '../js/shared/components/radio-chip' + +type Args = React.ComponentProps + +export const RadioChipDefault = (args: Args) => { + return +} + +export const RadioChipDisabled = (args: Args) => { + return +} + +export const RadioChipDisabledSelected = (args: Args) => { + return +} + +export default { + title: 'Shared / Components / RadioChip', + component: RadioChip, + args: { + label: 'Option', + }, +} diff --git a/services/web/frontend/stylesheets/_style_includes.less b/services/web/frontend/stylesheets/_style_includes.less index 2d4dc861df..009cd34e92 100644 --- a/services/web/frontend/stylesheets/_style_includes.less +++ b/services/web/frontend/stylesheets/_style_includes.less @@ -66,6 +66,7 @@ @import 'components/split-menu.less'; @import 'components/group-members.less'; @import 'components/stepper.less'; +@import 'components/radio-chip.less'; // Components w/ JavaScript @import 'components/modals.less'; diff --git a/services/web/frontend/stylesheets/components/radio-chip.less b/services/web/frontend/stylesheets/components/radio-chip.less new file mode 100644 index 0000000000..ebd4477d6f --- /dev/null +++ b/services/web/frontend/stylesheets/components/radio-chip.less @@ -0,0 +1,57 @@ +.radio-chip { + background: @white; + border: 1px solid @neutral-60; + border-radius: 999px; + color: @neutral-90; + display: inline-flex; + font-weight: 400; + gap: 4px; + inline-size: fit-content; + line-height: 1.4; + padding: 8px 16px 8px 8px; + + @media only screen and (max-width: @screen-sm-min) { + width: 100%; + } + + &:hover { + background: @neutral-20; + } + + &:focus-within { + box-shadow: 0px 0px 0px 2px @blue-30; + } + + input[type='radio'] { + accent-color: @green-50; + height: 16px; + margin: 4px; + width: 15px; + } +} + +.radio-chip[data-disabled='true'] { + border-color: @neutral-20; + + &:hover { + background: @white; + cursor: not-allowed; + } +} + +.radio-group-col-1 { + align-items: flex-start; + display: flex; + flex-direction: column; + gap: 16px; +} + +.radio-group-col-2 { + display: grid; + grid-gap: 16px; + grid-template-columns: 1fr 1fr; + + @media (max-width: @screen-sm-min) { + grid-template-columns: 1fr; + } +} diff --git a/services/web/frontend/stylesheets/main-style.less b/services/web/frontend/stylesheets/main-style.less index 3fda7c3163..4589142c2e 100644 --- a/services/web/frontend/stylesheets/main-style.less +++ b/services/web/frontend/stylesheets/main-style.less @@ -77,6 +77,7 @@ @import 'components/switch.less'; @import 'components/switcher.less'; @import 'components/stepper.less'; +@import 'components/radio-chip.less'; // Components w/ JavaScript @import 'components/modals.less'; diff --git a/services/web/frontend/stylesheets/modules/overleaf-integration.less b/services/web/frontend/stylesheets/modules/overleaf-integration.less index 170adbdab5..fddb28f59e 100644 --- a/services/web/frontend/stylesheets/modules/overleaf-integration.less +++ b/services/web/frontend/stylesheets/modules/overleaf-integration.less @@ -32,7 +32,7 @@ } #onboarding-data-collection { - width: 720px; + max-width: 720px; padding: 24px; margin: 0 auto; background: #fff; @@ -40,9 +40,13 @@ flex-direction: column; gap: 24px; - p { + .onboarding-question-title { font-size: 20px; - margin-bottom: 5px; + } + + p { + font-size: 16px; + margin-bottom: 16px; } .logo { @@ -60,6 +64,11 @@ justify-content: stretch; gap: 24px; + @media (max-width: @screen-xs-max) { + flex-direction: column; + gap: 0; + } + .form-group { flex-grow: 1; } diff --git a/services/web/locales/en.json b/services/web/locales/en.json index cb72a4cca7..5ae5b03b48 100644 --- a/services/web/locales/en.json +++ b/services/web/locales/en.json @@ -732,6 +732,7 @@ "help_articles_matching": "Help articles matching your subject", "help_improve_overleaf_fill_out_this_survey": "If you would like to help us improve Overleaf, please take a moment to fill out <0>this survey.", "help_us_spread_word": "Help us spread the word about __appName__", + "helps_us_tailor_your_experience": "This helps us tailor your Overleaf experience.", "hide_configuration": "Hide configuration", "hide_document_preamble": "Hide document preamble", "hide_outline": "Hide File outline", @@ -1318,6 +1319,12 @@ "press_and_awards": "Press & awards", "press_shortcut_to_open_advanced_reference_search": "Press __ctrlSpace__ or __altSpace__ to open Advanced Reference Search", "price": "Price", + "primarily_work_study_question": "Where do you primarily work or study?", + "primarily_work_study_question_government": "In the government", + "primarily_work_study_question_nonprofit_ngo": "In a nonprofit/NGO", + "primarily_work_study_question_other": "Other", + "primarily_work_study_question_private_company": "In a private company", + "primarily_work_study_question_university_school": "In a university or school", "primary_email_check_question": "Is <0>__email__ still your email address?", "priority_support": "Priority support", "priority_support_info": "Our helpful Support team will prioritise and escalate your support requests where necessary.", diff --git a/services/web/test/frontend/shared/components/radio-chip.test.tsx b/services/web/test/frontend/shared/components/radio-chip.test.tsx new file mode 100644 index 0000000000..08e0b1bfb1 --- /dev/null +++ b/services/web/test/frontend/shared/components/radio-chip.test.tsx @@ -0,0 +1,57 @@ +import { expect } from 'chai' +import { render, screen } from '@testing-library/react' +import RadioChip from '@/shared/components/radio-chip' + +describe('', function () { + const defaultProps = { + name: 'test', + label: 'Test', + value: 'testValue', + onChange: () => {}, + } + + describe('component renders and with label', function () { + it('renders and label is provided', function () { + render() + screen.getByText('Test') + }) + }) + + describe('props', function () { + it('should be checked when the checked prop is provided', function () { + render() + const radioChip = screen.getByRole('radio') as HTMLInputElement + expect(radioChip.checked).to.equal(true) + }) + + it('should be disabled when the disabled prop is provided', function () { + render() + const radioChip = screen.getByRole('radio') as HTMLInputElement + expect(radioChip.disabled).to.equal(true) + }) + + it('should have the required attribute when the required prop is provided', function () { + render() + const radioChip = screen.getByRole('radio') as HTMLInputElement + expect(radioChip.required).to.equal(true) + }) + + it('should use the provided name prop', function () { + render() + const radioChip = screen.getByRole('radio') as HTMLInputElement + expect(radioChip.name).to.equal('testName') + }) + + it('should use the provided value prop', function () { + render() + const radioChip = screen.getByRole('radio') as HTMLInputElement + expect(radioChip.value).to.equal('testValue') + }) + + it('should have the data-disabled attribute when the disabled prop is provided', function () { + render() + const label = screen.getByText('Test')?.closest('label') + expect(label?.getAttribute('data-disabled')).to.equal('true') + }) + }) +})