├── .changeset
├── README.md
└── config.json
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
├── labeler.yml
└── workflows
│ ├── changesets.yml
│ ├── chromatic.yml
│ ├── ci.yml
│ ├── deploy-storybook.yml
│ ├── labeler.yml
│ ├── project.yml
│ ├── snyk.yml
│ └── yarn-lock.yml
├── .gitignore
├── .husky
└── pre-commit
├── .nvmrc
├── .prettierignore
├── .storybook
├── main.js
├── manager.js
├── preview-head.html
├── preview.tsx
├── preview
│ ├── FocusManagerDecorator.tsx
│ ├── ThemeProviderDecorator.tsx
│ ├── backgrounds.ts
│ └── viewport.ts
└── theme.ts
├── .vscode
└── extensions.json
├── .yarn
└── releases
│ ├── yarn-1.22.18.cjs
│ └── yarn-1.22.19.cjs
├── .yarnrc
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── assets
└── logo.png
├── docs
├── CHANGELOG_v0-v3.md
├── README.md
├── components.stories.mdx
├── contributing
│ ├── overview.stories.mdx
│ └── stories.stories.mdx
├── development-kitchen.stories.mdx
├── eslint-plugins.stories.mdx
├── foundations.stories.mdx
├── release-notes
│ ├── v3.stories.mdx
│ ├── v4.stories.mdx
│ └── v5.stories.mdx
├── rfcs
│ ├── header-component-api.md
│ ├── images
│ │ └── header-component-api
│ │ │ ├── editorial-header.png
│ │ │ ├── header.png
│ │ │ ├── masthead-link.png
│ │ │ ├── masthead-links.png
│ │ │ ├── masthead-menu.png
│ │ │ ├── masthead-switch-item.png
│ │ │ ├── masthead-switch.png
│ │ │ ├── masthead.png
│ │ │ ├── navigation-expanded.png
│ │ │ ├── navigation-primary-link.png
│ │ │ ├── navigation-primary-links.png
│ │ │ ├── navigation-secondary-link.png
│ │ │ ├── navigation-secondary-links-group.png
│ │ │ ├── navigation-secondary-links-supplemental-link.png
│ │ │ ├── navigation-secondary-links.png
│ │ │ ├── subnav-link.png
│ │ │ ├── subnav.png
│ │ │ ├── support-buttons.png
│ │ │ └── support-thank-you.png
│ └── no-unusable-components-line-in-the-sand.md
└── source.stories.mdx
├── jest.config.js
├── nx.json
├── package.json
├── packages
└── @guardian
│ ├── eslint-plugin-source-foundations
│ ├── .eslintrc.json
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── README.stories.mdx
│ ├── jest.config.js
│ ├── jest.e2e.setup.js
│ ├── package.json
│ ├── rollup.config.js
│ ├── src
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ └── rules
│ │ │ ├── no-star-imports-or-exports.test.ts
│ │ │ ├── no-star-imports-or-exports.ts
│ │ │ ├── valid-import-path.test.ts
│ │ │ └── valid-import-path.ts
│ └── tsconfig.json
│ ├── eslint-plugin-source-react-components
│ ├── .eslintrc.json
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── README.stories.mdx
│ ├── jest.config.js
│ ├── jest.e2e.setup.js
│ ├── package.json
│ ├── rollup.config.js
│ ├── src
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ └── rules
│ │ │ ├── valid-import-path.test.ts
│ │ │ └── valid-import-path.ts
│ └── tsconfig.json
│ ├── source-foundations
│ ├── .yarnrc
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── jest.config.js
│ ├── jest.e2e.setup.js
│ ├── lib
│ │ └── jest-matchers
│ │ │ ├── index.ts
│ │ │ └── toBeValidCSS.ts
│ ├── package.json
│ ├── rollup.config.js
│ └── src
│ │ ├── accessibility
│ │ ├── accessibility.test.ts
│ │ ├── description-id.stories.mdx
│ │ ├── description-id.ts
│ │ ├── focus-halo.stories.mdx
│ │ ├── focus-halo.ts
│ │ ├── focus-style-manager.stories.mdx
│ │ ├── focus-style-manager.ts
│ │ ├── generate-source-id.stories.mdx
│ │ ├── generate-source-id.ts
│ │ ├── visually-hidden.stories.mdx
│ │ └── visually-hidden.ts
│ │ ├── animation
│ │ └── transitions.ts
│ │ ├── breakpoints
│ │ └── breakpoints.ts
│ │ ├── colour
│ │ ├── palette.stories.mdx
│ │ ├── palette.tsx
│ │ └── storybookColorPalette.tsx
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ ├── mq
│ │ ├── mq.stories.mdx
│ │ ├── mq.test.ts
│ │ └── mq.ts
│ │ ├── size
│ │ ├── size.stories.mdx
│ │ └── size.ts
│ │ ├── space
│ │ ├── space.stories.mdx
│ │ ├── space.test.ts
│ │ └── space.ts
│ │ ├── typography
│ │ ├── api.ts
│ │ ├── data.ts
│ │ ├── font-styles.ts
│ │ ├── index.ts
│ │ ├── obj
│ │ │ ├── index.ts
│ │ │ └── typography.obj.test.ts
│ │ ├── storybookTypographyRenderers.tsx
│ │ ├── types.ts
│ │ ├── typography.stories.mdx
│ │ └── typography.test.ts
│ │ └── utils
│ │ ├── px-to-rem.test.ts
│ │ ├── px-to-rem.ts
│ │ ├── resets.stories.mdx
│ │ ├── resets.test.ts
│ │ ├── resets.ts
│ │ ├── supports-queries.ts
│ │ └── svg-background-image.ts
│ ├── source-react-components-development-kitchen
│ ├── .github
│ │ └── pull_request_template.md
│ ├── .yarnrc
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── jest.config.js
│ ├── jest.e2e.setup.js
│ ├── package.json
│ ├── rollup.config.js
│ └── src
│ │ ├── divider
│ │ ├── Divider.stories.tsx
│ │ ├── Divider.tsx
│ │ ├── README.md
│ │ └── styles.ts
│ │ ├── editorial-button
│ │ ├── EditorialButton.stories.tsx
│ │ ├── EditorialButton.tsx
│ │ ├── EditorialLinkButton.stories.tsx
│ │ ├── EditorialLinkButton.tsx
│ │ ├── README.md
│ │ ├── styles.ts
│ │ └── types.ts
│ │ ├── expanding-wrapper
│ │ ├── ExpandingWrapper.stories.tsx
│ │ ├── ExpandingWrapper.tsx
│ │ ├── README.md
│ │ ├── styles.ts
│ │ ├── theme.ts
│ │ └── types.ts
│ │ ├── footer-with-contents
│ │ ├── FooterLinks.stories.tsx
│ │ ├── FooterLinks.tsx
│ │ ├── FooterWithContents.stories.tsx
│ │ ├── FooterWithContents.tsx
│ │ ├── README.md
│ │ ├── footerLinksStyles.ts
│ │ └── footerWithContentsStyles.ts
│ │ ├── index.test.ts
│ │ ├── index.ts
│ │ ├── lines
│ │ ├── DashedLines.tsx
│ │ ├── DottedLines.tsx
│ │ ├── Lines.stories.tsx
│ │ ├── Lines.tsx
│ │ ├── README.md
│ │ ├── SquigglyLines.tsx
│ │ └── StraightLines.tsx
│ │ ├── logo
│ │ ├── Logo.stories.tsx
│ │ ├── Logo.tsx
│ │ └── README.md
│ │ ├── numeric-input
│ │ ├── InputExtension.tsx
│ │ ├── NumericInput.stories.tsx
│ │ ├── NumericInput.tsx
│ │ ├── README.md
│ │ ├── inputExtensionStyles.ts
│ │ ├── numericInputStyles.ts
│ │ └── sharedStyles.ts
│ │ ├── quote-icon
│ │ ├── QuoteIcon.stories.tsx
│ │ ├── QuoteIcon.tsx
│ │ └── README.md
│ │ ├── star-rating
│ │ ├── README.md
│ │ ├── StarRating.stories.tsx
│ │ └── StarRating.tsx
│ │ ├── summary
│ │ ├── ErrorSummary.stories.tsx
│ │ ├── ErrorSummary.tsx
│ │ ├── InfoSummary.stories.tsx
│ │ ├── InfoSummary.tsx
│ │ ├── README.md
│ │ ├── SuccessSummary.stories.tsx
│ │ ├── SuccessSummary.tsx
│ │ ├── styles.ts
│ │ └── types.ts
│ │ ├── toggle-switch-apps
│ │ ├── README.md
│ │ ├── ToggleSwitchApps.stories.tsx
│ │ ├── ToggleSwitchApps.tsx
│ │ └── styles.ts
│ │ └── toggle-switch
│ │ ├── README.md
│ │ ├── ToggleSwitch.stories.tsx
│ │ ├── ToggleSwitch.tsx
│ │ └── styles.ts
│ └── source-react-components
│ ├── .yarnrc
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── jest.config.js
│ ├── jest.e2e.setup.js
│ ├── package.json
│ ├── rollup.config.js
│ ├── scripts
│ ├── README.md
│ ├── create-icons
│ │ ├── create-icon-component.ts
│ │ ├── create-readme.ts
│ │ ├── get-svgs-from-figma.ts
│ │ └── index.ts
│ └── vendor
│ │ └── icons
│ │ └── README.md
│ ├── src
│ ├── @types
│ │ ├── Icons.ts
│ │ ├── Props.ts
│ │ ├── Theme.ts
│ │ └── ThemeName.ts
│ ├── accordion
│ │ ├── Accordion.stories.tsx
│ │ ├── Accordion.tsx
│ │ ├── AccordionRow.tsx
│ │ ├── AccordionRowNoJS.tsx
│ │ ├── styles.ts
│ │ └── theme.ts
│ ├── brand
│ │ ├── SvgGuardianBestWebsiteLogo.stories.tsx
│ │ ├── SvgGuardianBestWebsiteLogo.tsx
│ │ ├── SvgGuardianLiveLogo.stories.tsx
│ │ ├── SvgGuardianLiveLogo.tsx
│ │ ├── SvgGuardianLogo.stories.tsx
│ │ ├── SvgGuardianLogo.tsx
│ │ ├── SvgRoundel.tsx
│ │ ├── SvgRoundelBrand.stories.tsx
│ │ ├── SvgRoundelBrand.tsx
│ │ ├── SvgRoundelBrandInverse.stories.tsx
│ │ ├── SvgRoundelBrandInverse.tsx
│ │ ├── SvgRoundelDefault.stories.tsx
│ │ ├── SvgRoundelDefault.tsx
│ │ ├── SvgRoundelInverse.stories.tsx
│ │ ├── SvgRoundelInverse.tsx
│ │ └── favicons
│ │ │ ├── 114x114-roundel.png
│ │ │ ├── 114x114.png
│ │ │ ├── 120x120.png
│ │ │ ├── 144x144.png
│ │ │ ├── 152x152-roundel.png
│ │ │ ├── 152x152.png
│ │ │ ├── 32x32-dev.ico
│ │ │ ├── 32x32.ico
│ │ │ ├── 57x57.png
│ │ │ └── 72x72.png
│ ├── button
│ │ ├── Button.stories.tsx
│ │ ├── Button.tsx
│ │ ├── LinkButton.stories.tsx
│ │ ├── LinkButton.tsx
│ │ ├── shared.tsx
│ │ ├── styles.ts
│ │ ├── theme-reader-revenue.ts
│ │ ├── theme.ts
│ │ └── types.ts
│ ├── checkbox
│ │ ├── Checkbox.stories.tsx
│ │ ├── Checkbox.tsx
│ │ ├── CheckboxGroup.stories.tsx
│ │ ├── CheckboxGroup.tsx
│ │ ├── LabelText.tsx
│ │ ├── SupportingText.tsx
│ │ ├── styles.ts
│ │ └── theme.ts
│ ├── choice-card
│ │ ├── ChoiceCard.stories.tsx
│ │ ├── ChoiceCard.tsx
│ │ ├── ChoiceCardGroup.stories.tsx
│ │ ├── ChoiceCardGroup.tsx
│ │ ├── styles.ts
│ │ └── theme.ts
│ ├── columns
│ │ ├── Column.tsx
│ │ ├── Columns.stories.tsx
│ │ ├── Columns.tsx
│ │ └── styles.ts
│ ├── container
│ │ ├── Container.stories.tsx
│ │ ├── Container.tsx
│ │ └── styles.ts
│ ├── deprecated-exports.ts
│ ├── footer
│ │ ├── BackToTop.stories.tsx
│ │ ├── BackToTop.tsx
│ │ ├── Footer.stories.tsx
│ │ ├── Footer.tsx
│ │ ├── styles.ts
│ │ └── theme.ts
│ ├── hide
│ │ ├── Hide.stories.tsx
│ │ └── Hide.tsx
│ ├── icons
│ │ ├── Icons.stories.tsx
│ │ ├── SvgSpinner.tsx
│ │ └── labels.ts
│ ├── index.test.ts
│ ├── index.ts
│ ├── inline
│ │ ├── Inline.stories.tsx
│ │ ├── Inline.tsx
│ │ ├── styles.ts
│ │ └── types.ts
│ ├── label
│ │ ├── Label.stories.tsx
│ │ ├── Label.tsx
│ │ ├── Legend.stories.tsx
│ │ ├── Legend.tsx
│ │ ├── SupportingText.tsx
│ │ ├── Text.tsx
│ │ ├── styles.ts
│ │ ├── theme.ts
│ │ └── types.ts
│ ├── link
│ │ ├── ButtonLink.stories.tsx
│ │ ├── ButtonLink.tsx
│ │ ├── Link.stories.tsx
│ │ ├── Link.tsx
│ │ ├── shared.tsx
│ │ ├── styles.ts
│ │ ├── theme.ts
│ │ └── types.ts
│ ├── radio
│ │ ├── Radio.stories.tsx
│ │ ├── Radio.tsx
│ │ ├── RadioGroup.stories.tsx
│ │ ├── RadioGroup.tsx
│ │ ├── styles.ts
│ │ └── theme.ts
│ ├── select
│ │ ├── Option.tsx
│ │ ├── Select.stories.tsx
│ │ ├── Select.tsx
│ │ ├── styles.ts
│ │ └── theme.ts
│ ├── stack
│ │ ├── Stack.stories.tsx
│ │ ├── Stack.tsx
│ │ └── styles.ts
│ ├── text-area
│ │ ├── TextArea.stories.tsx
│ │ ├── TextArea.tsx
│ │ └── styles.ts
│ ├── text-input
│ │ ├── TextInput.stories.tsx
│ │ ├── TextInput.tsx
│ │ ├── styles.ts
│ │ └── theme.ts
│ ├── tiles
│ │ ├── Tiles.stories.tsx
│ │ ├── Tiles.tsx
│ │ ├── styles.ts
│ │ └── types.ts
│ └── user-feedback
│ │ ├── InlineError.stories.tsx
│ │ ├── InlineError.tsx
│ │ ├── InlineSuccess.stories.tsx
│ │ ├── InlineSuccess.tsx
│ │ ├── styles.ts
│ │ ├── theme.ts
│ │ └── types.ts
│ └── vendor
│ └── icons
│ ├── README.md
│ ├── SvgAlertPhone.tsx
│ ├── SvgAlertRound.tsx
│ ├── SvgAlertTriangle.tsx
│ ├── SvgAppleBrand.tsx
│ ├── SvgArrowContract.tsx
│ ├── SvgArrowDownStraight.tsx
│ ├── SvgArrowExpand.tsx
│ ├── SvgArrowLeftStraight.tsx
│ ├── SvgArrowOutdent.tsx
│ ├── SvgArrowPopOut.tsx
│ ├── SvgArrowRightStraight.tsx
│ ├── SvgArrowScroll.tsx
│ ├── SvgArrowUpAndDownSmall.tsx
│ ├── SvgArrowUpStraight.tsx
│ ├── SvgArrowUpStraightSmall.tsx
│ ├── SvgAsterisk.tsx
│ ├── SvgAudio.tsx
│ ├── SvgAudioMute.tsx
│ ├── SvgBookMark.tsx
│ ├── SvgBookMarkCross.tsx
│ ├── SvgCalendar.tsx
│ ├── SvgCamera.tsx
│ ├── SvgCheckmark.tsx
│ ├── SvgChevronDownDouble.tsx
│ ├── SvgChevronDownSingle.tsx
│ ├── SvgChevronDownSingleXsmall.tsx
│ ├── SvgChevronLeftDouble.tsx
│ ├── SvgChevronLeftSingle.tsx
│ ├── SvgChevronRightDouble.tsx
│ ├── SvgChevronRightSingle.tsx
│ ├── SvgChevronUpDouble.tsx
│ ├── SvgChevronUpSingle.tsx
│ ├── SvgClock.tsx
│ ├── SvgClockBaselineSmall.tsx
│ ├── SvgCreditCard.tsx
│ ├── SvgCross.tsx
│ ├── SvgCrossRound.tsx
│ ├── SvgCrossedOutCloud.tsx
│ ├── SvgCrosswords.tsx
│ ├── SvgDirectDebit.tsx
│ ├── SvgDirectDebitWide.tsx
│ ├── SvgDocument.tsx
│ ├── SvgDownload.tsx
│ ├── SvgDragHandle.tsx
│ ├── SvgEdit.tsx
│ ├── SvgEllipsis.tsx
│ ├── SvgEnvelope.tsx
│ ├── SvgExclamation.tsx
│ ├── SvgExternal.tsx
│ ├── SvgEye.tsx
│ ├── SvgEyeStrike.tsx
│ ├── SvgFacebook.tsx
│ ├── SvgFacebookBrand.tsx
│ ├── SvgFacebookMessenger.tsx
│ ├── SvgFilter.tsx
│ ├── SvgGift.tsx
│ ├── SvgGlobe.tsx
│ ├── SvgGoogleBrand.tsx
│ ├── SvgGps.tsx
│ ├── SvgHandPointed.tsx
│ ├── SvgHouse.tsx
│ ├── SvgHouseCross.tsx
│ ├── SvgHousePlus.tsx
│ ├── SvgHouseSetting.tsx
│ ├── SvgIndent.tsx
│ ├── SvgInfoRound.tsx
│ ├── SvgLinkedIn.tsx
│ ├── SvgLocationMarker.tsx
│ ├── SvgMagnifyingGlass.tsx
│ ├── SvgMagnifyingGlassMinus.tsx
│ ├── SvgMagnifyingGlassPlus.tsx
│ ├── SvgMagnifyingGlassSadFace.tsx
│ ├── SvgMediaControlsBack.tsx
│ ├── SvgMediaControlsForward.tsx
│ ├── SvgMediaControlsPause.tsx
│ ├── SvgMediaControlsPlay.tsx
│ ├── SvgMediaControlsStop.tsx
│ ├── SvgMenu.tsx
│ ├── SvgMinus.tsx
│ ├── SvgMoon.tsx
│ ├── SvgNewsletter.tsx
│ ├── SvgNotificationsOff.tsx
│ ├── SvgNotificationsOn.tsx
│ ├── SvgPadlock.tsx
│ ├── SvgPartyOfThree.tsx
│ ├── SvgPayPalBrand.tsx
│ ├── SvgPerson.tsx
│ ├── SvgPersonCross.tsx
│ ├── SvgPersonPlus.tsx
│ ├── SvgPersonRound.tsx
│ ├── SvgPersonTick.tsx
│ ├── SvgPhone.tsx
│ ├── SvgPinned.tsx
│ ├── SvgPinterest.tsx
│ ├── SvgPlus.tsx
│ ├── SvgQuote.tsx
│ ├── SvgReload.tsx
│ ├── SvgSettings.tsx
│ ├── SvgShare.tsx
│ ├── SvgShareCallout.tsx
│ ├── SvgSpeechBubble.tsx
│ ├── SvgSpeechBubbleCross.tsx
│ ├── SvgSpeechBubblePlus.tsx
│ ├── SvgStar.tsx
│ ├── SvgStarOutline.tsx
│ ├── SvgTextLarge.tsx
│ ├── SvgTextSize.tsx
│ ├── SvgTextSmall.tsx
│ ├── SvgTickRound.tsx
│ ├── SvgTwitter.tsx
│ ├── SvgUpload.tsx
│ ├── SvgVideo.tsx
│ └── SvgWhatsApp.tsx
├── scripts
├── README.md
└── paths.ts
├── stylelint.config.js
├── tsconfig.json
└── yarn.lock
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@1.6.3/schema.json",
3 | "changelog": "@changesets/cli/changelog",
4 | "commit": false,
5 | "linked": [],
6 | "access": "public",
7 | "baseBranch": "main",
8 | "updateInternalDependencies": "patch",
9 | "ignore": [],
10 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": {
11 | "onlyUpdatePeerDependentsWhenOutOfRange": true
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # based on https://github.com/guardian/configs/blob/main/.editorconfig
2 |
3 | ; top-most EditorConfig file
4 | root = true
5 |
6 | [*]
7 | # Tabs for accessibility reasons:
8 | # - https://alexandersandberg.com/tabs-for-accessibility
9 | # - https://twitter.com/Rich_Harris/status/1541761871585464323
10 | # If it messes up your github previews, you can choose your favourite tab width:
11 | # - https://github.com/settings/appearance
12 | indent_style = tab
13 | end_of_line = lf
14 | charset = utf-8
15 | trim_trailing_whitespace = true
16 | insert_final_newline = true
17 |
18 | # Because `yml`
19 | [*.{yml,yaml}]
20 | indent_style = space
21 | indent_size = 2
22 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 |
4 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @guardian/client-side-infra
2 |
3 | /packages/@guardian/source-react-components-development-kitchen/src/components/button @guardian/dotcom-platform
4 | /packages/@guardian/source-react-components-development-kitchen/src/components/footer-with-contents @guardian/conversions-developers
5 | /packages/@guardian/source-react-components-development-kitchen/src/components/lines @guardian/dotcom-platform
6 | /packages/@guardian/source-react-components-development-kitchen/src/components/logo @guardian/dotcom-platform
7 | /packages/@guardian/source-react-components-development-kitchen/src/components/numeric-input @guardian/conversions-developers
8 | /packages/@guardian/source-react-components-development-kitchen/src/components/quote-icon @guardian/dotcom-platform
9 | /packages/@guardian/source-react-components-development-kitchen/src/components/star-rating @guardian/dotcom-platform
10 | /packages/@guardian/source-react-components-development-kitchen/src/components/summary @guardian/identity
11 | /packages/@guardian/source-react-components-development-kitchen/src/components/toggle-switch @guardian/mss-admins
12 | /packages/@guardian/source-react-components-development-kitchen/src/components/expanding-wrapper @guardian/editorial-experience
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 | ---
8 |
9 | **Describe the bug**
10 | A clear and concise description of what the bug is.
11 |
12 | **To Reproduce**
13 | Steps to reproduce the behavior:
14 |
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 |
28 | - OS: [e.g. iOS]
29 | - Browser [e.g. chrome, safari]
30 | - Version [e.g. 22]
31 |
32 | **Smartphone (please complete the following information):**
33 |
34 | - Device: [e.g. iPhone6]
35 | - OS: [e.g. iOS8.1]
36 | - Browser [e.g. stock browser, safari]
37 | - Version [e.g. 22]
38 |
39 | **Additional context**
40 | Add any other context about the problem here.
41 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 | ---
8 |
9 | **Is your feature request related to a problem? Please describe.**
10 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
11 |
12 | **Describe the solution you'd like**
13 | A clear and concise description of what you want to happen.
14 |
15 | **Describe alternatives you've considered**
16 | A clear and concise description of any alternative solutions or features you've considered.
17 |
18 | **Additional context**
19 | Add any other context or screenshots about the feature request here.
20 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: 'npm' # See documentation for possible values
9 | directory: '/' # Location of package manifests
10 | schedule:
11 | interval: 'monthly'
12 | day: 'monday'
13 | time: '06:00'
14 | open-pull-requests-limit: 1
15 | # Minimise the number of chromatic runs.
16 | # We've enabled 'Require branches to be up to date before merging',
17 | # so you won't be able to merge a dependabot PR unless you rebase manually anyway.
18 | rebase-strategy: 'disabled'
19 | - package-ecosystem: 'github-actions'
20 | directory: '/'
21 | schedule:
22 | interval: 'monthly'
23 | day: 'monday'
24 | time: '06:00'
25 |
--------------------------------------------------------------------------------
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | # https://github.com/marketplace/actions/labeler
2 |
3 | foundations:
4 | - 'packages/@guardian/source-foundations/**/*'
5 | react-components:
6 | - 'packages/@guardian/source-react-components/**/*'
7 | kitchen:
8 | - 'packages/@guardian/source-react-components-development-kitchen/**/*'
9 |
--------------------------------------------------------------------------------
/.github/workflows/changesets.yml:
--------------------------------------------------------------------------------
1 | name: Manage Changesets
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | changesets-version:
10 | name: Manage Changesets Pull Request
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout Repo
14 | uses: actions/checkout@v3
15 | with:
16 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
17 | fetch-depth: 0
18 |
19 | - uses: guardian/actions-setup-node@v2.4.1
20 | with:
21 | cache: 'yarn'
22 |
23 | - name: Install Dependencies
24 | run: yarn install --frozen-lockfile
25 |
26 | - name: Create Release Pull Request or Publish to npm
27 | id: changesets
28 | uses: changesets/action@v1
29 | with:
30 | publish: yarn release
31 | title: 'Release package updates'
32 | commit: 'Bump package versions'
33 | env:
34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
36 |
--------------------------------------------------------------------------------
/.github/workflows/chromatic.yml:
--------------------------------------------------------------------------------
1 | name: Chromatic
2 | on:
3 | push:
4 | jobs:
5 | upload-storybook:
6 | runs-on: ubuntu-latest
7 | steps:
8 | - uses: actions/checkout@v3
9 | with:
10 | fetch-depth: 0
11 | - uses: guardian/actions-setup-node@v2.4.1
12 | with:
13 | cache: 'yarn'
14 | - run: yarn install --frozen-lockfile
15 | - uses: chromaui/action@v1
16 | with:
17 | projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
18 | token: ${{ secrets.GITHUB_TOKEN }}
19 | buildScriptName: 'build:storybook'
20 | exitOnceUploaded: true
21 | onlyChanged: '!(main)' # only turbosnap on non-main branches
22 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-storybook.yml:
--------------------------------------------------------------------------------
1 | name: Deploy Storybook to GitHub Pages
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | deploy:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v3
11 | - uses: guardian/actions-setup-node@v2.4.1
12 | with:
13 | cache: 'yarn'
14 | - name: build
15 | run: |
16 | yarn install --frozen-lockfile
17 | yarn build:storybook
18 | - name: deploy
19 | run: yarn storybook-to-ghpages --ci
20 | env:
21 | GH_TOKEN: ${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}
22 |
--------------------------------------------------------------------------------
/.github/workflows/labeler.yml:
--------------------------------------------------------------------------------
1 | name: 'Pull Request Labeler'
2 | on:
3 | - pull_request_target
4 |
5 | jobs:
6 | label-pr:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/labeler@v4
10 | with:
11 | repo-token: '${{ secrets.GITHUB_TOKEN }}'
12 | sync-labels: true # remove redundant labels after a change
13 |
--------------------------------------------------------------------------------
/.github/workflows/project.yml:
--------------------------------------------------------------------------------
1 | name: Add new issues to CSTI project
2 |
3 | on:
4 | issues:
5 | types:
6 | - opened
7 |
8 | jobs:
9 | add-to-project:
10 | name: Add issue to project
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/add-to-project@v0.3.0
14 | with:
15 | # You can target a repository in a different organization
16 | # to the issue
17 | project-url: https://github.com/orgs/guardian/projects/61
18 | # uses a PAT from @sndrs
19 | github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
20 |
--------------------------------------------------------------------------------
/.github/workflows/snyk.yml:
--------------------------------------------------------------------------------
1 | # This action runs snyk monitor on every push to main
2 | name: Snyk
3 |
4 | on:
5 | push:
6 | branches:
7 | - main
8 | workflow_dispatch:
9 |
10 | jobs:
11 | security:
12 | uses: guardian/.github/.github/workflows/sbt-node-snyk.yml@main
13 | with:
14 | DEBUG: true
15 | ORG: guardian-csti
16 | SKIP_NODE: false
17 | secrets:
18 | SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
19 |
--------------------------------------------------------------------------------
/.github/workflows/yarn-lock.yml:
--------------------------------------------------------------------------------
1 | name: Yarn Lock Changes
2 | on: [pull_request]
3 |
4 | jobs:
5 | yarn_lock_changes:
6 | runs-on: ubuntu-latest
7 | # Permission overwrite is required for Dependabot PRs
8 | permissions:
9 | pull-requests: write
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v3
13 | - name: Yarn Lock Changes
14 | # Please use `main` as version before the stable release will be published as `v1`.
15 | uses: Simek/yarn-lock-changes@main
16 | with:
17 | token: ${{ secrets.GITHUB_TOKEN }}
18 | collapsibleThreshold: 150
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | dist
4 | .cache
5 | .DS_Store
6 | *.tgz
7 | package-lock.json
8 | .idea/
9 | .vscode/settings.json
10 | coverage/
11 | .eslintcache
12 | .vscode/
13 |
14 | # scripts/eslint-integration-test
15 | scripts/eslint-integration-test/integration-test-content.ts
16 |
17 | # Environment
18 | .env
19 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | yarn lint-staged
5 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 16.15.0
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .yarn
2 | dist
3 | node_modules
4 |
--------------------------------------------------------------------------------
/.storybook/manager.js:
--------------------------------------------------------------------------------
1 | import { addons } from '@storybook/addons';
2 | import { theme } from './theme';
3 |
4 | addons.setConfig({
5 | theme,
6 | });
7 |
--------------------------------------------------------------------------------
/.storybook/preview.tsx:
--------------------------------------------------------------------------------
1 | import { ThemeProviderDecorator } from './preview/ThemeProviderDecorator';
2 | import { FocusManagerDecorator } from './preview/FocusManagerDecorator';
3 | import { viewport } from './preview/viewport';
4 | import { backgrounds } from './preview/backgrounds';
5 |
6 | export const parameters = {
7 | viewport,
8 | backgrounds,
9 | actions: { argTypesRegex: '^on[A-Z].*' },
10 | controls: {
11 | matchers: {
12 | color: /(background|color)$/i,
13 | date: /Date$/,
14 | },
15 | },
16 | options: {
17 | storySort: {
18 | order: [
19 | 'Source',
20 | 'Foundations',
21 | 'Components',
22 | 'Development Kitchen',
23 | 'Packages',
24 | ],
25 | method: 'alphabetical',
26 | },
27 | },
28 | };
29 |
30 | export const decorators = [FocusManagerDecorator, ThemeProviderDecorator];
31 |
--------------------------------------------------------------------------------
/.storybook/preview/FocusManagerDecorator.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 | import { FocusStyleManager } from '@guardian/source-foundations';
3 |
4 | export const FocusManagerDecorator = (storyFn) => {
5 | useEffect(() => {
6 | FocusStyleManager.onlyShowFocusOnTabs();
7 | });
8 |
9 | return <>{storyFn()}>;
10 | };
11 |
--------------------------------------------------------------------------------
/.storybook/preview/ThemeProviderDecorator.tsx:
--------------------------------------------------------------------------------
1 | import { ThemeProvider } from '@emotion/react';
2 |
3 | export const ThemeProviderDecorator = (storyFn, context) => {
4 | const theme = context.parameters.theme;
5 | return theme ? (
6 | {storyFn()}
7 | ) : (
8 | <>{storyFn()}>
9 | );
10 | };
11 |
--------------------------------------------------------------------------------
/.storybook/preview/backgrounds.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 |
3 | export const backgrounds = {
4 | default: 'background.primary',
5 | values: [
6 | {
7 | name: 'background.primary',
8 | value: palette.neutral[100],
9 | },
10 | {
11 | name: 'background.secondary',
12 | value: palette.neutral[97],
13 | },
14 | {
15 | name: 'background.inverse',
16 | value: palette.neutral[10],
17 | },
18 | {
19 | name: 'brandBackground.primary',
20 | value: palette.brand[400],
21 | },
22 | {
23 | name: 'brandAltBackground.primary',
24 | value: palette.brandAlt[400],
25 | },
26 | ],
27 | };
28 |
--------------------------------------------------------------------------------
/.storybook/theme.ts:
--------------------------------------------------------------------------------
1 | import { create } from '@storybook/theming';
2 |
3 | export const theme = create({
4 | base: 'light',
5 | brandTitle: '@guardian/source',
6 | brandUrl: 'https://www.npmjs.com/package/@guardian/source',
7 | brandImage:
8 | 'https://raw.githubusercontent.com/guardian/source/main/assets/logo.png',
9 | });
10 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "editorconfig.editorconfig",
4 | "esbenp.prettier-vscode",
5 | "styled-components.vscode-styled-components",
6 | "stylelint.vscode-stylelint",
7 | "stkb.rewrap",
8 | "naumovs.color-highlight"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/.yarnrc:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | lastUpdateCheck 1633433443971
6 | yarn-path ".yarn/releases/yarn-1.22.19.cjs"
7 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Please read the [Contributing](https://guardian.github.io/source/?path=/story/contributing-overview--page) page in Storybook.
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Source
2 |
3 | > A component library for the Guardian's [Source Design System](https://theguardian.design).
4 |
5 | **Source packages have moved to https://github.com/guardian/csnx in [#252](https://github.com/guardian/csnx/pull/252)**.
6 |
7 | The last versions to be published from here were:
8 |
9 | - @guardian/source-foundations@7.0.1
10 | - @guardian/source-react-components@9.1.0
11 | - @guardian/source-react-components-development-kitchen@7.0.0
12 | - @guardian/eslint-plugin-source-foundations@7.0.0
13 | - @guardian/eslint-plugin-source-react-components@9.0.0
14 |
15 | https://github.com/guardian/source/releases
16 |
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/assets/logo.png
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | # Docs
2 |
3 | Please see our [Storybook docs](https://guardian.github.io/source)
4 |
--------------------------------------------------------------------------------
/docs/components.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 | import ReadMe from '../packages/@guardian/source-react-components/README.md';
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/development-kitchen.stories.mdx:
--------------------------------------------------------------------------------
1 | import ReadMe from '../packages/@guardian/source-react-components-development-kitchen/README.md';
2 | import { Meta } from '@storybook/addon-docs';
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/eslint-plugins.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
7 |
8 | # ESLint plugins
9 |
10 | The foundations and components packages have accompanying ESLint plugins which contain Source-specific linting rules that are highly recommended for your project.
11 |
12 | They can also work as codemods to help migrate your project to the next version of Source, using ESLint’s `--fix` option (beginning with v4):
13 |
14 | - [@guardian/eslint-plugin-source-foundations](https://guardian.github.io/source/?path=/story/packages-eslint-plugin-source-foundations)
15 | - [@guardian/eslint-plugin-source-react-components](https://guardian.github.io/source/?path=/story/packages-eslint-plugin-source-react-components)
16 |
--------------------------------------------------------------------------------
/docs/foundations.stories.mdx:
--------------------------------------------------------------------------------
1 | import ReadMe from '../packages/@guardian/source-foundations/README.md';
2 | import { Meta } from '@storybook/addon-docs';
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/editorial-header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/editorial-header.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/header.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/masthead-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/masthead-link.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/masthead-links.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/masthead-links.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/masthead-menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/masthead-menu.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/masthead-switch-item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/masthead-switch-item.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/masthead-switch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/masthead-switch.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/masthead.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/masthead.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/navigation-expanded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/navigation-expanded.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/navigation-primary-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/navigation-primary-link.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/navigation-primary-links.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/navigation-primary-links.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/navigation-secondary-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/navigation-secondary-link.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/navigation-secondary-links-group.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/navigation-secondary-links-group.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/navigation-secondary-links-supplemental-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/navigation-secondary-links-supplemental-link.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/navigation-secondary-links.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/navigation-secondary-links.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/subnav-link.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/subnav-link.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/subnav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/subnav.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/support-buttons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/support-buttons.png
--------------------------------------------------------------------------------
/docs/rfcs/images/header-component-api/support-thank-you.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/docs/rfcs/images/header-component-api/support-thank-you.png
--------------------------------------------------------------------------------
/docs/source.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
7 |
8 | # Source
9 |
10 | Our library for the web lives in the [Source repository](https://github.com/guardian/source). It consists of three packages:
11 |
12 | 1. [@guardian/source-foundations](https://guardian.github.io/source/?path=/story/foundations--page) – the foundations for our design system.
13 | 1. [@guardian/source-react-components](https://guardian.github.io/source/?path=/story/components--page) – a set of robust, accessible React components implemented using the foundations.
14 | 1. [@guardian/source-react-components-development-kitchen](https://guardian.github.io/source/?path=/story/development-kitchen--page) – an experimental set of React components for development and testing.
15 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2 | module.exports = {
3 | preset: 'ts-jest',
4 | testEnvironment: 'node',
5 | testPathIgnorePatterns: ['/node_modules', '/dist'],
6 | };
7 |
--------------------------------------------------------------------------------
/nx.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@nrwl/workspace/presets/npm.json",
3 | "npmScope": "guardian",
4 | "tasksRunnerOptions": {
5 | "default": {
6 | "runner": "@nrwl/nx-cloud",
7 | "options": {
8 | "cacheableOperations": ["build", "test", "e2e"],
9 | "accessToken": "YjlhZjRmOWQtNWQwNy00YzUyLTk0YzItZWY1NTk3OGExMDQ4fHJlYWQtd3JpdGU="
10 | }
11 | }
12 | },
13 | "targetDependencies": {
14 | "build": [
15 | {
16 | "target": "build",
17 | "projects": "dependencies"
18 | }
19 | ],
20 | "test": [
21 | {
22 | "target": "build",
23 | "projects": "dependencies"
24 | }
25 | ],
26 | "e2e": [
27 | {
28 | "target": "build",
29 | "projects": "self"
30 | },
31 | {
32 | "target": "build",
33 | "projects": "dependencies"
34 | }
35 | ]
36 | },
37 | "affected": {
38 | "defaultBase": "main"
39 | },
40 | "pluginsConfig": {
41 | "@nrwl/js": {
42 | "analyzeSourceFiles": false
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "settings": {
4 | "import/resolver": {
5 | "typescript": {
6 | "alwaysTryTypes": true
7 | }
8 | }
9 | },
10 | "env": {
11 | "jest": true,
12 | "browser": true,
13 | "node": true
14 | },
15 | "parserOptions": {
16 | "sourceType": "module",
17 | "ecmaVersion": 2020,
18 | "ecmaFeatures": {
19 | "modules": true
20 | },
21 | "project": "./tsconfig.json"
22 | },
23 | "extends": ["@guardian/eslint-config"],
24 | "ignorePatterns": ["dist", "coverage"],
25 | "overrides": [
26 | {
27 | "files": ["**/*.ts", "**/*.tsx"],
28 | "extends": ["@guardian/eslint-config-typescript"]
29 | }
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # @guardian/eslint-plugin-source-foundations
2 |
3 | ## 8.0.0
4 |
5 | ### Major Changes
6 |
7 | - aa4c2caa: Bump @guardian/libs to `^9.0.0`
8 |
9 | ## 7.0.0
10 |
11 | ### Major Changes
12 |
13 | - Updated `peerDependencies` [905c5148]
14 | - @guardian/source-foundations@7.0.0
15 |
16 | ## 6.0.1
17 |
18 | ### Patch Changes
19 |
20 | - 40e41a43: **No changes**: Patch bump to fix deploy to npm due to the major version already having been published and deleted
21 |
22 | ## 6.0.0
23 |
24 | ### Patch Changes
25 |
26 | - Updated dependencies [3823490a]
27 | - @guardian/source-foundations@6.0.0
28 |
29 | ## 5.0.1
30 |
31 | ### Patch Changes
32 |
33 | - 5c23c1d1: Remove `console.log` from `valid-foundations-import-path` rule
34 |
35 | ## 5.0.0
36 |
37 | ### Patch Changes
38 |
39 | - Updated dependencies [b87baf5c]
40 | - Updated dependencies [1e129d0b]
41 | - Updated dependencies [8bd1adce]
42 | - Updated dependencies [51f8737e]
43 | - Updated dependencies [f6865ac5]
44 | - Updated dependencies [34ec716d]
45 | - @guardian/source-foundations@5.0.0
46 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/README.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 | import ReadMe from './README.md';
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'ts-jest',
3 | testEnvironment: 'node',
4 | };
5 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/jest.e2e.setup.js:
--------------------------------------------------------------------------------
1 | // Mock `src/index` with whatever `package.json` points at.
2 | // This means we can run `src/index.test.ts` against `dist` instead.
3 |
4 | const dist = require('.');
5 |
6 | jest.mock('./src/index', () => dist);
7 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/rollup.config.js:
--------------------------------------------------------------------------------
1 | import ts from 'rollup-plugin-ts';
2 | import pkg from './package.json';
3 |
4 | const bundle = (config) => ({
5 | ...config,
6 | input: 'src/index.ts',
7 | });
8 |
9 | // eslint-disable-next-line import/no-default-export -- it's what rollup wants
10 | export default [
11 | bundle({
12 | plugins: [ts()],
13 | output: [
14 | {
15 | file: pkg.main,
16 | format: 'cjs',
17 | sourcemap: true,
18 | },
19 | {
20 | file: pkg.module,
21 | format: 'es',
22 | sourcemap: true,
23 | },
24 | ],
25 | }),
26 | ];
27 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/src/index.test.ts:
--------------------------------------------------------------------------------
1 | import * as pkgExports from './index';
2 |
3 | it('Should have exactly these exports', () => {
4 | expect(Object.keys(pkgExports).sort()).toEqual(['configs', 'rules']);
5 | });
6 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/src/index.ts:
--------------------------------------------------------------------------------
1 | import { noStarImportsOrExports } from './rules/no-star-imports-or-exports';
2 | import { validFoundationsImportPath } from './rules/valid-import-path';
3 |
4 | export const rules = {
5 | 'valid-foundations-import-path': validFoundationsImportPath,
6 | 'no-star-imports-or-exports': noStarImportsOrExports,
7 | };
8 |
9 | export const configs = {
10 | recommended: {
11 | plugins: ['@guardian/source-foundations', 'import'],
12 |
13 | rules: {
14 | '@guardian/source-foundations/valid-foundations-import-path': 'error',
15 | '@guardian/source-foundations/no-star-imports-or-exports': 'error',
16 | 'import/no-duplicates': 'error',
17 | },
18 | },
19 | };
20 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-foundations/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig.json",
3 | "compilerOptions": {
4 | "target": "es5",
5 | "module": "commonjs"
6 | },
7 | "exclude": ["src/rules/*.test.ts", "dist"],
8 | "include": ["src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-react-components/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "settings": {
4 | "import/resolver": {
5 | "typescript": {
6 | "alwaysTryTypes": true
7 | }
8 | }
9 | },
10 | "env": {
11 | "jest": true,
12 | "browser": true,
13 | "node": true
14 | },
15 | "parserOptions": {
16 | "sourceType": "module",
17 | "ecmaVersion": 2020,
18 | "ecmaFeatures": {
19 | "modules": true
20 | },
21 | "project": "./tsconfig.json"
22 | },
23 | "extends": ["@guardian/eslint-config"],
24 | "ignorePatterns": ["dist", "coverage"],
25 | "overrides": [
26 | {
27 | "files": ["**/*.ts", "**/*.tsx"],
28 | "extends": ["@guardian/eslint-config-typescript"]
29 | }
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-react-components/README.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 | import ReadMe from './README.md';
3 |
4 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-react-components/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | preset: 'ts-jest',
3 | testEnvironment: 'node',
4 | };
5 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-react-components/jest.e2e.setup.js:
--------------------------------------------------------------------------------
1 | // Mock `src/index` with whatever `package.json` points at.
2 | // This means we can run `src/index.test.ts` against `dist` instead.
3 |
4 | const dist = require('.');
5 |
6 | jest.mock('./src/index', () => dist);
7 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-react-components/rollup.config.js:
--------------------------------------------------------------------------------
1 | import ts from 'rollup-plugin-ts';
2 | import pkg from './package.json';
3 |
4 | const bundle = (config) => ({
5 | ...config,
6 | input: 'src/index.ts',
7 | });
8 |
9 | // eslint-disable-next-line import/no-default-export -- it's what rollup wants
10 | export default [
11 | bundle({
12 | plugins: [ts()],
13 | output: [
14 | {
15 | file: pkg.main,
16 | format: 'cjs',
17 | sourcemap: true,
18 | },
19 | {
20 | file: pkg.module,
21 | format: 'es',
22 | sourcemap: true,
23 | },
24 | ],
25 | }),
26 | ];
27 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-react-components/src/index.test.ts:
--------------------------------------------------------------------------------
1 | import * as pkgExports from './index';
2 |
3 | it('Should have exactly these exports', () => {
4 | expect(Object.keys(pkgExports).sort()).toEqual(['configs', 'rules']);
5 | });
6 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-react-components/src/index.ts:
--------------------------------------------------------------------------------
1 | import { validImportPath } from './rules/valid-import-path';
2 |
3 | export const rules = {
4 | 'valid-import-path': validImportPath,
5 | };
6 |
7 | export const configs = {
8 | recommended: {
9 | plugins: ['@guardian/source-react-components'],
10 |
11 | rules: {
12 | '@guardian/source-react-components/valid-import-path': 'error',
13 | },
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/@guardian/eslint-plugin-source-react-components/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../../tsconfig.json",
3 | "compilerOptions": {
4 | "target": "es5",
5 | "module": "commonjs"
6 | },
7 | "exclude": ["src/rules/*.test.ts", "dist"],
8 | "include": ["src"]
9 | }
10 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/.yarnrc:
--------------------------------------------------------------------------------
1 | version-tag-prefix source-foundations-v
2 | version-git-message "@guardian/source-foundations v%s"
3 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2 | module.exports = {
3 | preset: 'ts-jest',
4 | testEnvironment: 'node',
5 | setupFilesAfterEnv: ['./lib/jest-matchers/index.ts'],
6 | };
7 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/jest.e2e.setup.js:
--------------------------------------------------------------------------------
1 | // Mock `src/index` with whatever `package.json` points at.
2 | // This means we can run `src/index.test.ts` against `dist` instead.
3 |
4 | const dist = require('.');
5 |
6 | jest.mock('./src/index', () => dist);
7 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/lib/jest-matchers/index.ts:
--------------------------------------------------------------------------------
1 | // Registers our custom jest matchers before running tests.
2 |
3 | // Register the toBeValidCSS matcher
4 | require('./toBeValidCSS');
5 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guardian/source-foundations",
3 | "version": "7.0.1",
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/guardian/source.git"
7 | },
8 | "license": "Apache-2.0",
9 | "sideEffects": false,
10 | "main": "dist/cjs/index.js",
11 | "module": "dist/esm/index.js",
12 | "files": [
13 | "dist"
14 | ],
15 | "scripts": {
16 | "build": "rollup -c",
17 | "clean": "rm -rf dist",
18 | "e2e": "jest src/index.test.ts --setupFilesAfterEnv=./jest.e2e.setup.js",
19 | "test": "jest --coverage"
20 | },
21 | "dependencies": {
22 | "mini-svg-data-uri": "^1.3.3"
23 | },
24 | "devDependencies": {
25 | "jest": "^27.2.3",
26 | "lightningcss": "^1.16.0",
27 | "rollup": "^2.75.4",
28 | "rollup-plugin-ts": "^2.0.7",
29 | "ts-jest": "^27.0.5"
30 | },
31 | "publishConfig": {
32 | "access": "public"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/rollup.config.js:
--------------------------------------------------------------------------------
1 | import ts from 'rollup-plugin-ts';
2 | import pkg from './package.json';
3 |
4 | const bundle = (config) => ({
5 | ...config,
6 | input: 'src/index.ts',
7 | external: (id) => !/^[./]/.test(id),
8 | });
9 |
10 | // eslint-disable-next-line import/no-default-export -- it's what rollup wants
11 | export default [
12 | bundle({
13 | plugins: [ts({ tsconfig: '../../../tsconfig.json' })],
14 | output: [
15 | {
16 | dir: pkg.main.replace('/index.js', ''),
17 | format: 'cjs',
18 | sourcemap: true,
19 | preserveModules: true,
20 | },
21 | {
22 | dir: pkg.module.replace('/index.js', ''),
23 | format: 'es',
24 | sourcemap: true,
25 | preserveModules: true,
26 | },
27 | ],
28 | }),
29 | ];
30 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/accessibility.test.ts:
--------------------------------------------------------------------------------
1 | import { focusHalo, focusHaloSpaced } from './focus-halo';
2 | import { visuallyHidden } from './visually-hidden';
3 |
4 | test('focusHalo should be a valid CSS fragment', () => {
5 | expect(focusHalo).toBeValidCSS({ isFragment: true });
6 | });
7 |
8 | test('focusHaloSpaced should be a valid CSS fragment', () => {
9 | expect(focusHaloSpaced).toBeValidCSS({ isFragment: true });
10 | });
11 |
12 | test('visuallyHidden should be a valid CSS fragment', () => {
13 | expect(visuallyHidden).toBeValidCSS({ isFragment: true });
14 | });
15 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/description-id.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
7 |
8 | # `descriptionId`
9 |
10 | A function that takes the ID of an element and generates a new ID. This should be set as the ID of an element that describes the first element. The generated ID should also be passed to the `aria-describedby` attribute on the first element.
11 |
12 | ```tsx
13 | import { descriptionId } from '@guardian/source-foundations';
14 |
15 | const Form = () => {
16 | const id = 'first_name';
17 | return (
18 |
22 | );
23 | };
24 | ```
25 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/description-id.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-foundations-descriptionid--page)
3 | *
4 | * Takes the ID of an element and generates a new ID. This should be set as the ID of an element that describes the first element. The generated ID should also be passed to the `aria-describedby` attribute on the first element.
5 | *
6 | * @param {string} id - ID of an element
7 | * @returns {string} ID of an element that describes the first element
8 | *
9 | * @example
10 | *
14 | */
15 | export const descriptionId = (id: string): string => `${id}_description`;
16 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/focus-halo.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 | import { focusHalo } from './focus-halo';
4 |
5 |
9 |
10 | # `focusHalo`
11 |
12 | Providing a clear focus state (the blue halo effect around active elements) is essential to support keyboard navigation.
13 |
14 | Apply the `focusHalo` style to custom interactive elements:
15 |
16 | ```tsx
17 | import { focusHalo } from '@guardian/source-foundations';
18 |
19 | const customButtonStyles = css`
20 | ${focusHalo};
21 | `;
22 | ```
23 |
24 | # `focusHaloSpaced`
25 |
26 | The blue halo effect with additional spacing between the element and the halo for better visibility of halo on blue-coloured elements.
27 |
28 | Apply the `focusHaloSpaced` style to custom interactive elements:
29 |
30 | ```tsx
31 | import { focusHaloSpaced } from '@guardian/source-foundations';
32 |
33 | const customButtonStyles = css`
34 | ${focusHaloSpaced};
35 | `;
36 | ```
37 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/focus-halo.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '../colour/palette';
2 |
3 | /**
4 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-foundations-focushalo--page)
5 | *
6 | * CSS rules that provide a clear visual focus state to support keyboard navigation.
7 | */
8 | export const focusHalo = `
9 | outline: 0;
10 | html:not(.src-focus-disabled) & {
11 | box-shadow: 0 0 0 5px ${palette.focus[400]};
12 | }
13 | `;
14 |
15 | export const focusHaloSpaced = `
16 | outline: 0;
17 | html:not(.src-focus-disabled) & {
18 | outline: 5px solid ${palette.focus[400]};
19 | outline-offset: 3px;
20 | }
21 | `;
22 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/focus-style-manager.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 | import { FocusStyleManager } from './focus-style-manager';
3 |
4 |
8 |
9 | # `FocusStyleManager`
10 |
11 | While providing a clear focus state is essential to support keyboard navigation, it is less important for mouse users.
12 |
13 | Source provides a utility that manages the appearance of focus styles. When enabled, focus styles will be hidden while the user interacts using the mouse. They will appear when the tab key is pressed to begin keyboard navigation.
14 |
15 | You should explictly enable this feature in your app:
16 |
17 | ```tsx
18 | import { FocusStyleManager } from '@guardian/source-foundations';
19 |
20 | FocusStyleManager.onlyShowFocusOnTabs();
21 | ```
22 |
23 | ## API
24 |
25 | ### FocusStyleManager.isActive()
26 |
27 | Returns whether the FocusStyleManager is currently running.
28 |
29 | ### FocusStyleManager.onlyShowFocusOnTabs()
30 |
31 | Enable behavior which hides focus styles during mouse interaction.
32 |
33 | ### FocusStyleManager.alwaysShowFocus()
34 |
35 | Stop this behavior (focus styles are always visible).
36 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/generate-source-id.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
7 |
8 | # `generateSourceId`
9 |
10 | A function that generates a unique ID for an element of the form `src-component-X` where `X` is a number.
11 |
12 | ```tsx
13 | import { generateSourceId } from '@guardian/source-foundations';
14 |
15 | const Form = () => {
16 | const id = generateSourceId();
17 | return (
18 |
21 | );
22 | };
23 | ```
24 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/generate-source-id.ts:
--------------------------------------------------------------------------------
1 | let sourceIdIndex = 0;
2 |
3 | export const generateSourceId = (): string =>
4 | `src-component-${sourceIdIndex++}`;
5 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/accessibility/visually-hidden.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
7 |
8 | # `visuallyHidden`
9 |
10 | Some elements should be presented only to screen reader users e.g. restyled checkboxes and button labels that provide more contextual information to the user.
11 |
12 | Apply the `visuallyHidden` CSS rules to elements that need to be hidden from sighted users but displayed to screen reader users:
13 |
14 | ```tsx
15 | import { visuallyHidden } from '@guardian/source-foundations';
16 |
17 | const label = css`
18 | ${visuallyHidden};
19 | `;
20 | ```
21 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/animation/transitions.ts:
--------------------------------------------------------------------------------
1 | const transitions = {
2 | short: '.2s cubic-bezier(.64, .57, .67, 1.53)',
3 | medium: '.3s ease-in-out',
4 | long: '.65s ease-in-out',
5 | };
6 |
7 | export { transitions };
8 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/breakpoints/breakpoints.ts:
--------------------------------------------------------------------------------
1 | export type Breakpoint =
2 | | 'mobile'
3 | | 'mobileMedium'
4 | | 'mobileLandscape'
5 | | 'phablet'
6 | | 'tablet'
7 | | 'desktop'
8 | | 'leftCol'
9 | | 'wide';
10 |
11 | /**
12 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-foundations-media-queries--page) •
13 | * [Design System](https://theguardian.design/2a1e5182b/p/41be19-grids)
14 | */
15 | export const breakpoints = {
16 | mobile: 320,
17 | mobileMedium: 375,
18 | mobileLandscape: 480,
19 | phablet: 660,
20 | tablet: 740,
21 | desktop: 980,
22 | leftCol: 1140,
23 | wide: 1300,
24 | } as const;
25 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/mq/mq.test.ts:
--------------------------------------------------------------------------------
1 | import type { Breakpoint } from '../breakpoints/breakpoints';
2 | import { breakpoints } from '../breakpoints/breakpoints';
3 | import { between, from, until } from './mq';
4 |
5 | it('from should return a min-width media query', () => {
6 | const min: Breakpoint = 'mobile';
7 |
8 | expect(from[min]).toBe(`@media (min-width: ${`${breakpoints[min]}px`})`);
9 | });
10 |
11 | it('until should return a max-width media query', () => {
12 | const max: Breakpoint = 'wide';
13 |
14 | expect(until[max]).toBe(`@media (max-width: ${`${breakpoints[max] - 1}px`})`);
15 | });
16 |
17 | it('between should return a media query with min- and max-width', () => {
18 | const min: Breakpoint = 'tablet';
19 | const max: Breakpoint = 'desktop';
20 |
21 | expect(between[min].and[max]).toBe(
22 | `@media (min-width: ${`${breakpoints[min]}px`}) and (max-width: ${`${
23 | breakpoints[max] - 1
24 | }px`})`,
25 | );
26 | });
27 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/space/space.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
7 |
8 | # Space
9 |
10 | Space units create visual rhythm and balance
11 |
12 | ## Example
13 |
14 | ```tsx
15 | import { space } from '@guardian/source-foundations';
16 |
17 | const container = css`
18 | margin: ${space[1]}px;
19 | `;
20 |
21 | /*
22 | .class-name {
23 | margin: 4px;
24 | }
25 | */
26 | ```
27 |
28 | ## Space scale
29 |
30 | The following units can be applied to margin or padding properties, vertically
31 | or horizontally.
32 |
33 | - `space[1]` -> 4px
34 | - `space[2]` -> 8px
35 | - `space[3]` -> 12px
36 | - `space[4]` -> 16px
37 | - `space[5]` -> 20px
38 | - `space[6]` -> 24px
39 | - `space[9]` -> 36px
40 | - `space[12]` -> 48px
41 | - `space[24]` -> 96px
42 |
43 | The same scale is also available as rems:
44 |
45 | - `remSpace[1]` -> 0.25rem
46 | - `remSpace[2]` -> 0.5rem
47 | - `remSpace[3]` -> 0.75rem
48 | - `remSpace[4]` -> 1rem
49 | - `remSpace[5]` -> 1.25rem
50 | - `remSpace[6]` -> 1.5rem
51 | - `remSpace[9]` -> 2.25rem
52 | - `remSpace[12]` -> 3rem
53 | - `remSpace[24]` -> 6rem
54 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/space/space.test.ts:
--------------------------------------------------------------------------------
1 | import { remSpace, space } from './space';
2 |
3 | it('should provide a rem equivalent of the pixel space', () =>
4 | expect(remSpace[2]).toBe(`${space[2] / 16}rem`));
5 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/typography/obj/index.ts:
--------------------------------------------------------------------------------
1 | import { body, headline, textSans, titlepiece } from '../api';
2 | import {
3 | bodySizes,
4 | fonts,
5 | fontWeights,
6 | headlineSizes,
7 | lineHeights,
8 | remBodySizes,
9 | remHeadlineSizes,
10 | remTextSansSizes,
11 | remTitlepieceSizes,
12 | textSansSizes,
13 | titlepieceSizes,
14 | } from '../data';
15 |
16 | export {
17 | titlepiece,
18 | headline,
19 | body,
20 | textSans,
21 | titlepieceSizes,
22 | headlineSizes,
23 | bodySizes,
24 | textSansSizes,
25 | remTitlepieceSizes,
26 | remHeadlineSizes,
27 | remBodySizes,
28 | remTextSansSizes,
29 | fonts,
30 | fontWeights,
31 | lineHeights,
32 | };
33 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/utils/px-to-rem.test.ts:
--------------------------------------------------------------------------------
1 | import { pxToRem, rootPixelFontSize } from './px-to-rem';
2 |
3 | it('should calculate a rem equivalent of a pixel value', () => {
4 | const value = 17;
5 | const result = pxToRem(value);
6 | expect(result).toBe(value / rootPixelFontSize);
7 | });
8 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/utils/px-to-rem.ts:
--------------------------------------------------------------------------------
1 | export const rootPixelFontSize = 16;
2 | export const pxToRem = (px: number): number => px / rootPixelFontSize;
3 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/utils/resets.stories.mdx:
--------------------------------------------------------------------------------
1 | import { Meta } from '@storybook/addon-docs';
2 |
3 |
7 |
8 | # CSS reset
9 |
10 | Source provides an optional CSS reset that sets some sensible default CSS rules. The intention is to provide a base for a consistent environment across projects and browsers.
11 |
12 | In a future major version, consuming the reset will become mandatory for consumers of Source.
13 |
14 | We recommend adopting this reset today.
15 |
16 | ## Example
17 |
18 | ```tsx
19 | import { resets } from '@guardian/source-foundations';
20 |
21 | const document = () => (
22 |
23 |
24 |
25 |
26 | {/* … */}
27 |
28 | );
29 | ```
30 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/utils/resets.test.ts:
--------------------------------------------------------------------------------
1 | import { resets } from './resets';
2 |
3 | test('resets.defaults should be valid CSS', () => {
4 | expect(resets.defaults).toBeValidCSS();
5 | });
6 |
7 | test('resets.fieldset should be a valid CSS fragment', () => {
8 | expect(resets.fieldset).toBeValidCSS({ isFragment: true });
9 | });
10 |
11 | test('resets.input should be an invalid CSS fragment', () => {
12 | // We add a test here so we don't forget to add/update a test
13 | // when this is converted to CSS in the future.
14 | expect(resets.input).not.toBeValidCSS({ isFragment: true });
15 | });
16 |
17 | test('resets.legend should be a valid CSS fragment', () => {
18 | expect(resets.legend).toBeValidCSS({ isFragment: true });
19 | });
20 |
21 | test('resets.resetCSS should be valid CSS', () => {
22 | expect(resets.resetCSS).toBeValidCSS();
23 | });
24 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/utils/supports-queries.ts:
--------------------------------------------------------------------------------
1 | export const appearance =
2 | '(appearance: none) or (-webkit-appearance: none) or (-moz-appearance: none)';
3 |
--------------------------------------------------------------------------------
/packages/@guardian/source-foundations/src/utils/svg-background-image.ts:
--------------------------------------------------------------------------------
1 | import svgToTinyDataUri from 'mini-svg-data-uri';
2 |
3 | export const svgBackgroundImage = (svg: string): string => {
4 | return `url("${svgToTinyDataUri(svg.replace(/\s\s+/g, ' '))}")`;
5 | };
6 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## What does this change?
2 |
3 | -
4 |
5 | ## Checklist
6 |
7 | - [ ] This change captured in a [a story](https://storybook.js.org/docs/react/writing-stories/introduction)
8 | - [ ] A designer seen this change
9 |
10 |
11 |
12 | ## Screenshots
13 |
14 | ### Before
15 |
16 | ### After
17 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/.yarnrc:
--------------------------------------------------------------------------------
1 | version-tag-prefix kitchen-v
2 | version-git-message "@guardian/source-react-components-development-kitchen v%s"
3 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2 | module.exports = {
3 | preset: 'ts-jest',
4 | testEnvironment: 'node',
5 | };
6 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/jest.e2e.setup.js:
--------------------------------------------------------------------------------
1 | // Mock `src/index` with whatever `package.json` points at.
2 | // This means we can run `src/index.test.ts` against `dist` instead.
3 |
4 | const dist = require('.');
5 |
6 | jest.mock('./src/index', () => dist);
7 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guardian/source-react-components-development-kitchen",
3 | "version": "7.0.0",
4 | "license": "Apache-2.0",
5 | "sideEffects": false,
6 | "main": "dist/cjs/index.js",
7 | "module": "dist/esm/index.js",
8 | "files": [
9 | "dist"
10 | ],
11 | "scripts": {
12 | "build": "rollup -c",
13 | "clean": "rm -rf dist",
14 | "test": "jest --coverage",
15 | "e2e": "jest src/index.test.ts --setupFilesAfterEnv=./jest.e2e.setup.js"
16 | },
17 | "devDependencies": {
18 | "mini-svg-data-uri": "^1.3.3",
19 | "npm-run-all": "^4.1.5",
20 | "rollup": "^2.75.4",
21 | "rollup-plugin-ts": "^2.0.7",
22 | "tslib": "^2.4.0",
23 | "web-vitals": "^2.0.0"
24 | },
25 | "peerDependencies": {
26 | "@emotion/react": "^11.0.0",
27 | "@guardian/libs": "^9.0.0",
28 | "@guardian/source-foundations": "^7.0.0",
29 | "@guardian/source-react-components": "^9.0.0",
30 | "react": "^17.0.1"
31 | },
32 | "publishConfig": {
33 | "access": "public"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/rollup.config.js:
--------------------------------------------------------------------------------
1 | import ts from 'rollup-plugin-ts';
2 | import pkg from './package.json';
3 |
4 | const bundle = (config) => ({
5 | ...config,
6 | input: 'src/index.ts',
7 | external: (id) => !/^[./]/.test(id),
8 | });
9 |
10 | // eslint-disable-next-line import/no-default-export -- it's what rollup wants
11 | export default [
12 | bundle({
13 | plugins: [ts({ tsconfig: '../../../tsconfig.json' })],
14 | output: [
15 | {
16 | dir: pkg.main.replace('/index.js', ''),
17 | format: 'cjs',
18 | sourcemap: true,
19 | preserveModules: true,
20 | },
21 | {
22 | dir: pkg.module.replace('/index.js', ''),
23 | format: 'es',
24 | sourcemap: true,
25 | preserveModules: true,
26 | },
27 | ],
28 | }),
29 | ];
30 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/divider/README.md:
--------------------------------------------------------------------------------
1 | # `Divider`
2 |
3 | Inserts a line on the page acting as a section break dividing content
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-divider--playground)
22 |
23 | ### How to use
24 |
25 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design).
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/divider/styles.ts:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export const fullStyles = css`
4 | margin-left: -10px;
5 | width: calc(100% + 20px);
6 | `;
7 | export const partialStyles = css`
8 | margin-left: -10px;
9 | width: 160px;
10 | `;
11 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/editorial-button/README.md:
--------------------------------------------------------------------------------
1 | # EditorialButton
2 |
3 | This is the editorial version of the core `Button` coomponent. This editorial version
4 | requires the `format` prop and uses that to override `Button` styles based on
5 | `format.theme`
6 |
7 | Also exported is `EditorialLinkButton` which, like in core, offers a href version of the buttom
8 |
9 | ## Install
10 |
11 | ```sh
12 | $ yarn add @guardian/source-react-components-development-kitchen
13 | ```
14 |
15 | or
16 |
17 | ```sh
18 | $ npm i @guardian/source-react-components-development-kitchen
19 | ```
20 |
21 | ## Use
22 |
23 | ### API
24 |
25 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-editorial-button--playground)
26 |
27 | ### How to use
28 |
29 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design/2a1e5182b/p/435225-button).
30 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/editorial-button/types.ts:
--------------------------------------------------------------------------------
1 | import type { ArticleFormat } from '@guardian/libs';
2 |
3 | export interface SharedEditorialButtonProps {
4 | /**
5 | * A format object denoting the style of the button using the enums
6 | * available from [@guardian/libs](https://github.com/guardian/libs/blob/main/src/format.ts).
7 | *
8 | * For example:
9 | *
10 | * ```ts
11 | * {
12 | * display: Display.Standard,
13 | * design: Design.Article,
14 | * theme: Pillar.News,
15 | * }
16 | * ```
17 | */
18 | format?: ArticleFormat;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/expanding-wrapper/README.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | The Expanding Wrapper wraps around any children, and collapses the block so it takes up less space on screen. The children can be expanded via a 'Show More' button, and collapsed again via a 'Show Less' Button. Additional content can be rendered inline with the show/hide button.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | #### `ExpandingWrapper`
22 |
23 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-expanding-wrapper--playground)
24 |
25 | ### How to use
26 |
27 | For context and visual guides relating to usage see the [Source Design System website](https://www.theguardian.design/2a1e5182b/p/108ed3-user-feedback/b/3803b4/t/08c895).
28 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/expanding-wrapper/theme.ts:
--------------------------------------------------------------------------------
1 | import type { Theme as EmotionTheme } from '@emotion/react';
2 | import { palette } from '@guardian/source-foundations';
3 |
4 | export const expandingWrapperThemeDefault = {
5 | expander: {
6 | border: palette.neutral[86],
7 | expandBackground: palette.neutral[7],
8 | expandText: palette.neutral[100],
9 | collapseBackground: palette.neutral[100],
10 | collapseText: palette.neutral[7],
11 | },
12 | };
13 | export const expandingWrapperDarkTheme = {
14 | expander: {
15 | border: palette.neutral[60],
16 | expandBackground: palette.neutral[86],
17 | expandText: palette.neutral[7],
18 | collapseBackground: palette.neutral[10],
19 | collapseText: palette.neutral[86],
20 | },
21 | };
22 |
23 | export interface Theme extends EmotionTheme {
24 | expander?: typeof expandingWrapperThemeDefault.expander;
25 | }
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/expanding-wrapper/types.ts:
--------------------------------------------------------------------------------
1 | import type { ReactElement } from 'react';
2 |
3 | export interface ExpandingWrapperProps {
4 | children: ReactElement;
5 | name: string;
6 | disableTabbingWhenCollapsed?: boolean;
7 | renderExtra?: () => ReactElement;
8 | expandCallback?: (expanded: boolean) => void;
9 | }
10 |
11 | export type TabbableElementType =
12 | | HTMLInputElement
13 | | HTMLTextAreaElement
14 | | HTMLSelectElement
15 | | HTMLButtonElement
16 | | HTMLAnchorElement;
17 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/footer-with-contents/FooterLinks.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { FooterLinksProps } from './FooterLinks';
3 | import { defaultGuardianLinks, FooterLinks } from './FooterLinks';
4 |
5 | export default {
6 | title: 'Packages/source-react-components-development-kitchen/FooterLinks',
7 | component: FooterLinks,
8 | parameters: {
9 | layout: 'fullscreen',
10 | },
11 | };
12 |
13 | const Template: Story = (args: FooterLinksProps) => (
14 |
15 | );
16 |
17 | // *****************************************************************************
18 |
19 | export const DefaultFooterLinks = Template.bind({});
20 |
21 | // *****************************************************************************
22 |
23 | export const FooterLinksInColumns = Template.bind({});
24 | FooterLinksInColumns.args = {
25 | links: [
26 | ...defaultGuardianLinks,
27 | {
28 | href: '/',
29 | text: 'About us',
30 | },
31 | ],
32 | };
33 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/footer-with-contents/FooterWithContents.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import {
3 | DefaultFooterLinks,
4 | FooterLinksInColumns,
5 | } from './FooterLinks.stories';
6 | import type { FooterWithContentsProps } from './FooterWithContents';
7 | import { FooterWithContents } from './FooterWithContents';
8 |
9 | export default {
10 | title:
11 | 'Packages/source-react-components-development-kitchen/FooterWithContents',
12 | component: FooterWithContents,
13 | parameters: {
14 | layout: 'fullscreen',
15 | },
16 | };
17 |
18 | const Template: Story = (
19 | args: FooterWithContentsProps,
20 | ) => ;
21 |
22 | // *****************************************************************************
23 |
24 | export const DefaultFooterWithContents = Template.bind({});
25 | DefaultFooterWithContents.args = {
26 | children: ,
27 | };
28 |
29 | // *****************************************************************************
30 |
31 | export const FooterWithColumnLinks = Template.bind({});
32 | FooterWithColumnLinks.args = {
33 | children: ,
34 | };
35 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/footer-with-contents/README.md:
--------------------------------------------------------------------------------
1 | # `Footer With Contents`
2 |
3 | A footer component that can have content added inside of it, and a footer links component to be used to display links within the footer.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-divider--playground)
22 |
23 | ### How to use
24 |
25 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design).
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/footer-with-contents/footerWithContentsStyles.ts:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import {
3 | brand,
4 | from,
5 | neutral,
6 | space,
7 | textSans,
8 | } from '@guardian/source-foundations';
9 |
10 | export const footer = css`
11 | background-color: ${brand[400]};
12 | color: ${neutral[100]};
13 | padding-bottom: ${space[1]}px;
14 | ${textSans.medium()};
15 | `;
16 |
17 | export const contentWrapperStyles = css`
18 | display: flex;
19 | position: relative;
20 | `;
21 |
22 | export const copyrightStyles = css`
23 | display: block;
24 | ${textSans.xxsmall()};
25 | padding-top: ${space[6]}px;
26 | padding-bottom: 18px;
27 | ${from.tablet} {
28 | padding-top: ${space[3]}px;
29 | }
30 | `;
31 |
32 | export const backToTopStyles = css`
33 | background-color: ${brand[400]};
34 | padding: 0 ${space[2]}px;
35 | position: absolute;
36 | bottom: -21px;
37 | right: ${space[3]}px;
38 | ${from.tablet} {
39 | padding: 0 5px;
40 | right: 0;
41 | }
42 | `;
43 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/index.test.ts:
--------------------------------------------------------------------------------
1 | import * as pkgExports from './index';
2 |
3 | // this makes sure no type exports have been removed
4 | // it won't catch that new ones have been added, but can anyone?
5 | export type {
6 | EditorialButtonProps,
7 | EditorialLinkButtonProps,
8 | ExpandingWrapperProps,
9 | FooterLinksProps,
10 | FooterWithContentsProps,
11 | LineCount,
12 | LinesProps,
13 | LogoProps,
14 | NumericInput,
15 | NumericInputProps,
16 | HeadlineSize,
17 | QuoteIconProps,
18 | StarRatingProps,
19 | ToggleSwitchProps,
20 | ToggleSwitchAppsProps,
21 | } from './index';
22 |
23 | it('Should have exactly these exports', () => {
24 | expect(Object.keys(pkgExports).sort()).toEqual([
25 | 'DashedLines',
26 | 'Divider',
27 | 'DottedLines',
28 | 'EditorialButton',
29 | 'EditorialLinkButton',
30 | 'ErrorSummary',
31 | 'ExpandingWrapper',
32 | 'FooterLinks',
33 | 'FooterWithContents',
34 | 'InfoSummary',
35 | 'Lines',
36 | 'Logo',
37 | 'NumericInput',
38 | 'QuoteIcon',
39 | 'SquigglyLines',
40 | 'StarRating',
41 | 'StraightLines',
42 | 'SuccessSummary',
43 | 'ToggleSwitch',
44 | 'ToggleSwitchApps',
45 | 'defaultGuardianLinks',
46 | ]);
47 | });
48 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/lines/README.md:
--------------------------------------------------------------------------------
1 | # Lines
2 |
3 | 📣 For more context and visual guides relating to lines usage, visit the [Source Design System website](https://www.theguardian.design)
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-lines--playground)
22 |
23 | ### How to use
24 |
25 | For context and visual guides relating to usage see the [Source Design System website](https://www.theguardian.design).
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/logo/README.md:
--------------------------------------------------------------------------------
1 | # QuoteIcon
2 |
3 | The Guardian logo appears in the header on most editorial pages
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-logo--playground)
22 |
23 | ### How to use
24 |
25 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design).
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/numeric-input/InputExtension.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | inputExtension,
3 | inputPrefix,
4 | inputSuffix,
5 | } from './inputExtensionStyles';
6 | import type { InputTheme } from './NumericInput';
7 | import { errorInput, successInput } from './sharedStyles';
8 |
9 | type InputExtensionProps = {
10 | children: string;
11 | type: 'prefix' | 'suffix';
12 | error?: string;
13 | success?: string;
14 | };
15 |
16 | export const InputExtension = ({
17 | children,
18 | type,
19 | error,
20 | success,
21 | }: InputExtensionProps) => {
22 | const style = type === 'prefix' ? inputPrefix : inputSuffix;
23 |
24 | return (
25 | [
28 | inputExtension(theme.textInput),
29 | error ? errorInput(theme.textInput) : '',
30 | !error && success ? successInput(theme.textInput) : '',
31 | style,
32 | ]}
33 | >
34 | {children}
35 |
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/numeric-input/README.md:
--------------------------------------------------------------------------------
1 | # `Numeric Input`
2 |
3 | A component for taking numeric input such as currency. Can display a prefix and/or suffix to add visual context for the user.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-numericinput--playground)
22 |
23 | ### How to use
24 |
25 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design).
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/numeric-input/inputExtensionStyles.ts:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import { space } from '@guardian/source-foundations';
3 | import { textInputThemeDefault } from '@guardian/source-react-components';
4 | import { inputBase } from './sharedStyles';
5 |
6 | export const inputExtension = (input = textInputThemeDefault.textInput) => css`
7 | ${inputBase(input)}
8 | display: inline-flex;
9 | align-items: center;
10 | `;
11 |
12 | export const inputPrefix = css`
13 | padding-right: ${space[1]}px;
14 | border-right: none;
15 | `;
16 |
17 | export const inputSuffix = css`
18 | padding-left: ${space[1]}px;
19 | border-left: none;
20 | `;
21 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/quote-icon/README.md:
--------------------------------------------------------------------------------
1 | # QuoteIcon
2 |
3 | The Guardian quote icon is used in kickers, headlines, drop caps and pull quotes to denote quoted text.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-quote-icon--playground)
22 |
23 | ### How to use
24 |
25 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design).
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/star-rating/README.md:
--------------------------------------------------------------------------------
1 | # StarRating
2 |
3 | Displays a rating, 1-5, using star SVGs. See the accompanying stories for visual examples.
4 |
5 | 📣 For more context and visual guides relating to `StarRating` usage, visit the [Source Design System website](https://www.theguardian.design).
6 |
7 | ## Install
8 |
9 | ```sh
10 | $ yarn add @guardian/source-react-components-development-kitchen
11 | ```
12 |
13 | or
14 |
15 | ```sh
16 | $ npm i @guardian/source-react-components-development-kitchen
17 | ```
18 |
19 | ## Use
20 |
21 | ### API
22 |
23 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-star-rating--playground)
24 |
25 | ### How to use
26 |
27 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design).
28 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/summary/ErrorSummary.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import { error as errorColors } from '@guardian/source-foundations';
3 | import { SvgAlertTriangle } from '@guardian/source-react-components';
4 | import {
5 | contextStyles,
6 | iconStyles,
7 | messageStyles,
8 | messageWrapperStyles,
9 | wrapperStyles,
10 | } from './styles';
11 | import type { SummaryProps } from './types';
12 |
13 | export interface ErrorSummaryProps extends SummaryProps {
14 | /**
15 | * The error report link URL
16 | */
17 | errorReportUrl?: string;
18 | }
19 |
20 | export const ErrorSummary = ({
21 | message,
22 | errorReportUrl,
23 | context,
24 | cssOverrides,
25 | ...props
26 | }: ErrorSummaryProps): EmotionJSX.Element => (
27 |
41 | );
42 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/summary/InfoSummary.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import { brand as brandColors, text } from '@guardian/source-foundations';
3 | import { SvgInfo } from '@guardian/source-react-components';
4 | import {
5 | contextStyles,
6 | iconStyles,
7 | messageStyles,
8 | messageWrapperStyles,
9 | wrapperStyles,
10 | } from './styles';
11 | import type { SummaryProps } from './types';
12 |
13 | export type InfoSummaryProps = SummaryProps;
14 |
15 | export const InfoSummary = ({
16 | message,
17 | context,
18 | cssOverrides,
19 | ...props
20 | }: InfoSummaryProps): EmotionJSX.Element => (
21 |
22 |
23 |
24 |
25 |
26 |
{message}
27 | {context &&
{context}
}
28 |
29 |
30 | );
31 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/summary/README.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | Summary messages appear at the top of a group of content to summarise any actions that the user has taken or errors that have occurred.
4 |
5 | There are three components available, `ErrorSummary`, `SuccessSummary`, and `InfoSummary`.
6 |
7 | ## Install
8 |
9 | ```sh
10 | $ yarn add @guardian/source-react-components-development-kitchen
11 | ```
12 |
13 | or
14 |
15 | ```sh
16 | $ npm i @guardian/source-react-components-development-kitchen
17 | ```
18 |
19 | ## Use
20 |
21 | ### API
22 |
23 | #### `ErrorSummary`
24 |
25 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-error-summary--playground)
26 |
27 | #### `Success Summary`
28 |
29 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-success-summary--playground)
30 |
31 | #### `Info Summary`
32 |
33 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-info-summary--playground)
34 |
35 | ### How to use
36 |
37 | For context and visual guides relating to usage see the [Source Design System website](https://www.theguardian.design/2a1e5182b/p/108ed3-user-feedback/b/3803b4/t/08c895).
38 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/summary/SuccessSummary.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import { success as successColors } from '@guardian/source-foundations';
3 | import { SvgTickRound } from '@guardian/source-react-components';
4 | import {
5 | contextStyles,
6 | iconStyles,
7 | messageStyles,
8 | messageWrapperStyles,
9 | wrapperStyles,
10 | } from './styles';
11 | import type { SummaryProps } from './types';
12 |
13 | export type SuccessSummaryProps = SummaryProps;
14 |
15 | export const SuccessSummary = ({
16 | message,
17 | context,
18 | cssOverrides,
19 | ...props
20 | }: SuccessSummaryProps): EmotionJSX.Element => (
21 |
22 |
23 |
24 |
25 |
26 |
{message}
27 | {context &&
{context}
}
28 |
29 |
30 | );
31 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/summary/styles.ts:
--------------------------------------------------------------------------------
1 | import type { SerializedStyles } from '@emotion/react';
2 | import { css } from '@emotion/react';
3 | import { size, space, textSans } from '@guardian/source-foundations';
4 |
5 | export const wrapperStyles = (color: string): SerializedStyles => css`
6 | border: 4px solid ${color};
7 | padding: ${space[1]}px;
8 |
9 | display: flex;
10 | `;
11 |
12 | export const iconStyles = (color: string): SerializedStyles => css`
13 | display: flex;
14 | flex: 0 1 auto;
15 | margin-top: 1px;
16 | svg {
17 | fill: ${color};
18 | height: ${size.xsmall}px;
19 | width: ${size.xsmall}px;
20 | }
21 | `;
22 |
23 | export const messageStyles = (
24 | color: string,
25 | isBold = true,
26 | ): SerializedStyles => css`
27 | ${textSans.medium({
28 | fontWeight: isBold ? 'bold' : 'regular',
29 | lineHeight: 'loose',
30 | })}
31 | color: ${color};
32 | `;
33 |
34 | export const messageWrapperStyles = css`
35 | margin-left: ${space[1]}px;
36 | `;
37 |
38 | export const contextStyles = css`
39 | ${textSans.medium()}
40 | `;
41 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/summary/types.ts:
--------------------------------------------------------------------------------
1 | import type { Props } from '@guardian/source-react-components';
2 |
3 | export interface SummaryProps extends Props {
4 | /**
5 | * The main message of the component
6 | * e.g. the main error message, success message etc.
7 | */
8 | message: React.ReactNode;
9 | /**
10 | * Optional context information about the message
11 | */
12 | context?: React.ReactNode;
13 | }
14 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/toggle-switch-apps/README.md:
--------------------------------------------------------------------------------
1 | # ToggleSwitchApps
2 |
3 | Displays an on/off switch for use in apps web views. See the accompanying stories for visual examples.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-toggle-switch-apps--playground)
22 |
23 | ### How to use
24 |
25 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design).
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components-development-kitchen/src/toggle-switch/README.md:
--------------------------------------------------------------------------------
1 | # ToggleSwitch
2 |
3 | Displays an on/off switch for web. See the accompanying stories for visual examples.
4 |
5 | ## Install
6 |
7 | ```sh
8 | $ yarn add @guardian/source-react-components-development-kitchen
9 | ```
10 |
11 | or
12 |
13 | ```sh
14 | $ npm i @guardian/source-react-components-development-kitchen
15 | ```
16 |
17 | ## Use
18 |
19 | ### API
20 |
21 | See [storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-development-kitchen-toggle-switch--playground)
22 |
23 | ### How to use
24 |
25 | For context and visual guides relating to usage see the [Source Design System website](https://theguardian.design).
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/.yarnrc:
--------------------------------------------------------------------------------
1 | version-tag-prefix source-react-components-v
2 | version-git-message "@guardian/source-react-components v%s"
3 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/jest.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2 | module.exports = {
3 | preset: 'ts-jest',
4 | testEnvironment: 'node',
5 | };
6 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/jest.e2e.setup.js:
--------------------------------------------------------------------------------
1 | // Mock `src/index` with whatever `package.json` points at.
2 | // This means we can run `src/index.test.ts` against `dist` instead.
3 |
4 | const dist = require('.');
5 |
6 | jest.mock('./src/index', () => dist);
7 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@guardian/source-react-components",
3 | "version": "9.1.0",
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/guardian/source.git"
7 | },
8 | "license": "Apache-2.0",
9 | "sideEffects": false,
10 | "main": "dist/cjs/src/index.js",
11 | "module": "dist/esm/src/index.js",
12 | "files": [
13 | "dist"
14 | ],
15 | "scripts": {
16 | "build": "rollup -c",
17 | "clean": "rm -rf dist",
18 | "create-icons": "ts-node scripts/create-icons",
19 | "e2e": "jest src/index.test.ts --setupFilesAfterEnv=./jest.e2e.setup.js",
20 | "test": "jest --coverage"
21 | },
22 | "devDependencies": {
23 | "@rollup/plugin-node-resolve": "^13.3.0",
24 | "@svgr/babel-preset": "^6.3.1",
25 | "@svgr/core": "^6.3.1",
26 | "@svgr/plugin-jsx": "^6.3.1",
27 | "@svgr/plugin-prettier": "^6.3.1",
28 | "@svgr/plugin-svgo": "^6.3.1",
29 | "@types/mkdirp": "^1.0.2",
30 | "@types/svgo": "^2.6.3",
31 | "axios": "^0.27.2",
32 | "mkdirp": "^1.0.4",
33 | "rollup": "^2.77.2",
34 | "rollup-plugin-ts": "^2.0.7",
35 | "ts-node": "^10.7.0"
36 | },
37 | "peerDependencies": {
38 | "@emotion/react": "^11.0.0",
39 | "@guardian/source-foundations": "^7.0.0",
40 | "react": "^17.0.1"
41 | },
42 | "publishConfig": {
43 | "access": "public"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/rollup.config.js:
--------------------------------------------------------------------------------
1 | import nodeResolve from '@rollup/plugin-node-resolve';
2 | import ts from 'rollup-plugin-ts';
3 | import pkg from './package.json';
4 |
5 | const external = ['@guardian/source-foundations', 'react', /@emotion\/react/];
6 |
7 | // eslint-disable-next-line import/no-default-export -- it's what rollup wants
8 | export default [
9 | {
10 | input: 'src/index.ts',
11 | output: [
12 | {
13 | dir: pkg.main.replace('/src/index.js', ''),
14 | format: 'cjs',
15 | sourcemap: true,
16 | preserveModules: true,
17 | },
18 | {
19 | dir: pkg.module.replace('/src/index.js', ''),
20 | format: 'es',
21 | sourcemap: true,
22 | preserveModules: true,
23 | },
24 | ],
25 | external,
26 | plugins: [
27 | nodeResolve({ extensions: ['.ts', '.tsx', '.mjs', '.jsx', '.js'] }),
28 | ts({ tsconfig: '../../../tsconfig.json' }),
29 | ],
30 | },
31 | ];
32 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/scripts/README.md:
--------------------------------------------------------------------------------
1 | # `@guardian/source-react-components` scripts
2 |
3 | ## `create-icons`
4 |
5 | Pulls the SVG source of icons from Figma and generates react components from them using [SVGR](https://github.com/gregberge/svgr).
6 |
7 | Run the script using the following command:
8 |
9 | ```sh
10 | yarn workspace @guardian/source-react-components create-icons
11 | ```
12 |
13 | It requires a Personal Access Token (PAT) to authenticate against the Figma API.
14 |
15 | 1. [Create a token](https://www.figma.com/developers/api#access-tokens)
16 | 2. Create an environment variable called `FIGMA_TOKEN`, using the token as the value.
17 |
18 | _Note:_ The script does not run as part of the build process to ensure we don't inadvertently pick up changes to icons as part of an unrelated change.
19 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/scripts/create-icons/create-readme.ts:
--------------------------------------------------------------------------------
1 | import { ICON_FILE } from './get-svgs-from-figma';
2 |
3 | export const createReadme = () => `# Icons
4 |
5 | **The contents of this directory are created automatically. Any edits will be
6 | overwritten sooner or later.**
7 |
8 | The SVGs for these icons are automatically pulled in from the [source design file in
9 | Figma](https://www.figma.com/file/${ICON_FILE}/%E2%97%90-Icons?node-id=55%3A2)
10 | using the create-icons script via the Figma API:
11 |
12 | \`\`\`sh
13 | yarn workspace @guardian/source-react-components create-icons
14 | \`\`\`
15 | `;
16 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/scripts/vendor/icons/README.md:
--------------------------------------------------------------------------------
1 | # Icons
2 |
3 | **The contents of this directory are created automatically. Any edits will be
4 | overwritten sooner or later.**
5 |
6 | The SVGs for these icons are automatically pulled in from the [source design file in
7 | Figma](https://www.figma.com/file/Ai7AELHC6KCz38qKZkvuHo/%E2%97%90-Icons?node-id=55%3A2)
8 | using the fetch-icons script via the Figma API:
9 |
10 | ```sh
11 | yarn workspace @guardian/source-react-components create-icons
12 | ```
13 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/@types/Icons.ts:
--------------------------------------------------------------------------------
1 | export type IconSize = 'xsmall' | 'small' | 'medium';
2 |
3 | export interface IconProps {
4 | size?: IconSize;
5 | isAnnouncedByScreenReader?: boolean;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/@types/Props.ts:
--------------------------------------------------------------------------------
1 | import type { SerializedStyles } from '@emotion/react';
2 |
3 | export interface Props {
4 | className?: string;
5 | /**
6 | * Override component styles by passing in the result of [emotion's `css` function/prop](https://emotion.sh/docs/introduction).
7 | */
8 | cssOverrides?: SerializedStyles | SerializedStyles[];
9 | }
10 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/@types/ThemeName.ts:
--------------------------------------------------------------------------------
1 | export type ThemeName = 'default' | 'brand' | 'brandAlt';
2 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/accordion/Accordion.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { AccordionProps } from './Accordion';
3 | import { Accordion } from './Accordion';
4 | import { AccordionRow } from './AccordionRow';
5 |
6 | export default {
7 | title: 'Packages/source-react-components/Accordion',
8 | component: Accordion,
9 | subcomponents: { AccordionRow },
10 | args: {
11 | hideToggleLabel: false,
12 | },
13 | };
14 |
15 | const Template: Story = (args: AccordionProps) => (
16 |
17 |
18 | Present your card to a newsagent each time you collect the paper. The
19 | newsagent will scan your card and will be reimbursed for each transaction
20 | automatically.
21 |
22 |
23 | Simply give your preferred store / retailer the barcode printed on your
24 | subscription letter.
25 |
26 |
27 | );
28 |
29 | export const WithCTALabelsDefaultTheme = Template.bind({});
30 |
31 | // *****************************************************************************
32 |
33 | export const WithoutCTALabelsDefaultTheme = Template.bind({});
34 | WithoutCTALabelsDefaultTheme.args = {
35 | hideToggleLabel: true,
36 | };
37 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/accordion/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 |
3 | export const accordionThemeDefault = {
4 | accordion: {
5 | textPrimary: palette.neutral[7],
6 | borderPrimary: palette.neutral[60],
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgGuardianBestWebsiteLogo.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { SvgGuardianBestWebsiteLogoProps } from './SvgGuardianBestWebsiteLogo';
3 | import { SvgGuardianBestWebsiteLogo } from './SvgGuardianBestWebsiteLogo';
4 |
5 | export default {
6 | title: 'Packages/source-react-components/SvgGuardianBestWebsiteLogo',
7 | component: SvgGuardianBestWebsiteLogo,
8 | argTypes: {
9 | width: {
10 | control: { type: 'range', min: 10, max: 600 },
11 | },
12 | },
13 | };
14 |
15 | const Template: Story = (args: SvgGuardianBestWebsiteLogoProps) => (
16 |
17 | );
18 |
19 | export const Default = Template.bind({});
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgGuardianLiveLogo.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { SvgGuardianLiveLogoProps } from './SvgGuardianLiveLogo';
3 | import { SvgGuardianLiveLogo } from './SvgGuardianLiveLogo';
4 |
5 | export default {
6 | title: 'Packages/source-react-components/SvgGuardianLiveLogo',
7 | component: SvgGuardianLiveLogo,
8 | argTypes: {
9 | width: {
10 | control: { type: 'range', min: 10, max: 600 },
11 | },
12 | },
13 | };
14 |
15 | const Template: Story = (args: SvgGuardianLiveLogoProps) => (
16 |
17 | );
18 |
19 | export const Default = Template.bind({});
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgGuardianLogo.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { SvgGuardianLogoProps } from './SvgGuardianLogo';
3 | import { SvgGuardianLogo } from './SvgGuardianLogo';
4 |
5 | export default {
6 | title: 'Packages/source-react-components/SvgGuardianLogo',
7 | component: SvgGuardianLogo,
8 | argTypes: {
9 | width: {
10 | control: { type: 'range', min: 10, max: 600 },
11 | },
12 | },
13 | };
14 |
15 | const Template: Story = (args: SvgGuardianLogoProps) => (
16 |
17 | );
18 |
19 | export const Default = Template.bind({});
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgRoundelBrand.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { SvgRoundelBrandProps } from './SvgRoundelBrand';
3 | import { SvgRoundelBrand } from './SvgRoundelBrand';
4 |
5 | export default {
6 | title: 'Packages/source-react-components/SvgRoundelBrand',
7 | component: SvgRoundelBrand,
8 | argTypes: {
9 | width: {
10 | control: { type: 'range', min: 10, max: 600 },
11 | },
12 | },
13 | };
14 |
15 | const Template: Story = (args: SvgRoundelBrandProps) => (
16 |
17 | );
18 |
19 | export const Default = Template.bind({});
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgRoundelBrand.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import { brand } from '@guardian/source-foundations';
3 | import { SvgRoundel } from './SvgRoundel';
4 |
5 | export type SvgRoundelBrandProps = {
6 | /**
7 | * The width the SVG will display at (height is automatically adjusted
8 | * to maintain the correct aspect ratio).
9 | */
10 | width?: number;
11 | };
12 |
13 | /**
14 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-svgroundelbrand--playground) •
15 | * [Design System](https://theguardian.design/2a1e5182b/p/8909e0-assets/t/37168b) •
16 | * [GitHub](https://github.com/guardian/source/tree/main/packages/@guardian/source-react-components/src/brand/SvgRoundelBrand.tsx) •
17 | * [NPM](https://www.npmjs.com/package/@guardian/source-react-components)
18 | */
19 | export const SvgRoundelBrand = (
20 | args: SvgRoundelBrandProps,
21 | ): EmotionJSX.Element => {
22 | return (
23 |
24 | );
25 | };
26 | SvgRoundelBrand.args = {
27 | width: 300,
28 | };
29 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgRoundelBrandInverse.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { SvgRoundelBrandInverseProps } from './SvgRoundelBrandInverse';
3 | import { SvgRoundelBrandInverse } from './SvgRoundelBrandInverse';
4 |
5 | export default {
6 | title: 'Packages/source-react-components/SvgRoundelBrandInverse',
7 | component: SvgRoundelBrandInverse,
8 | argTypes: {
9 | width: {
10 | control: { type: 'range', min: 10, max: 600 },
11 | },
12 | },
13 | };
14 |
15 | const Template: Story = (args: SvgRoundelBrandInverseProps) => (
16 |
17 | );
18 |
19 | export const Default = Template.bind({});
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgRoundelBrandInverse.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import { brand } from '@guardian/source-foundations';
3 | import { SvgRoundel } from './SvgRoundel';
4 |
5 | export type SvgRoundelBrandInverseProps = {
6 | /**
7 | * The width the SVG will display at (height is automatically adjusted
8 | * to maintain the correct aspect ratio).
9 | */
10 | width?: number;
11 | };
12 |
13 | /**
14 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-svgroundelbrandinverse--playground) •
15 | * [Design System](https://theguardian.design/2a1e5182b/p/8909e0-assets/t/37168b) •
16 | * [GitHub](https://github.com/guardian/source/tree/main/packages/@guardian/source-react-components/src/brand/SvgRoundelBrandInverse.tsx) •
17 | * [NPM](https://www.npmjs.com/package/@guardian/source-react-components)
18 | */
19 | export const SvgRoundelBrandInverse = (
20 | args: SvgRoundelBrandInverseProps,
21 | ): EmotionJSX.Element => {
22 | return (
23 |
24 | );
25 | };
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgRoundelDefault.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { SvgRoundelDefaultProps } from './SvgRoundelDefault';
3 | import { SvgRoundelDefault } from './SvgRoundelDefault';
4 |
5 | export default {
6 | title: 'Packages/source-react-components/SvgRoundelDefault',
7 | component: SvgRoundelDefault,
8 | argTypes: {
9 | width: {
10 | control: { type: 'range', min: 10, max: 600 },
11 | },
12 | },
13 | };
14 |
15 | const Template: Story = (args: SvgRoundelDefaultProps) => (
16 |
17 | );
18 |
19 | export const Default = Template.bind({});
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgRoundelDefault.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import { neutral } from '@guardian/source-foundations';
3 | import { SvgRoundel } from './SvgRoundel';
4 |
5 | export type SvgRoundelDefaultProps = {
6 | /**
7 | * The width the SVG will display at (height is automatically adjusted
8 | * to maintain the correct aspect ratio).
9 | */
10 | width?: number;
11 | };
12 |
13 | /**
14 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-svgroundeldefault--playground) •
15 | * [Design System](https://theguardian.design/2a1e5182b/p/8909e0-assets/t/37168b) •
16 | * [GitHub](https://github.com/guardian/source/tree/main/packages/@guardian/source-react-components/src/brand/SvgRoundelDefault.tsx) •
17 | * [NPM](https://www.npmjs.com/package/@guardian/source-react-components)
18 | */
19 | export const SvgRoundelDefault = (
20 | args: SvgRoundelDefaultProps,
21 | ): EmotionJSX.Element => {
22 | return (
23 |
24 | );
25 | };
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgRoundelInverse.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import type { SvgRoundelInverseProps } from './SvgRoundelInverse';
3 | import { SvgRoundelInverse } from './SvgRoundelInverse';
4 |
5 | export default {
6 | title: 'Packages/source-react-components/SvgRoundelInverse',
7 | component: SvgRoundelInverse,
8 | argTypes: {
9 | width: {
10 | control: { type: 'range', min: 10, max: 600 },
11 | },
12 | },
13 | };
14 |
15 | const Template: Story = (args: SvgRoundelInverseProps) => (
16 |
17 | );
18 |
19 | export const Default = Template.bind({});
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/SvgRoundelInverse.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import { neutral } from '@guardian/source-foundations';
3 | import { SvgRoundel } from './SvgRoundel';
4 |
5 | export type SvgRoundelInverseProps = {
6 | /**
7 | * The width the SVG will display at (height is automatically adjusted
8 | * to maintain the correct aspect ratio).
9 | */
10 | width?: number;
11 | };
12 |
13 | /**
14 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-svgroundelinverse--playground) •
15 | * [Design System](https://theguardian.design/2a1e5182b/p/8909e0-assets/t/37168b) •
16 | * [GitHub](https://github.com/guardian/source/tree/main/packages/@guardian/source-react-components/src/brand/SvgRoundelInverse.tsx) •
17 | * [NPM](https://www.npmjs.com/package/@guardian/source-react-components)
18 | */
19 | export const SvgRoundelInverse = (
20 | args: SvgRoundelInverseProps,
21 | ): EmotionJSX.Element => {
22 | return (
23 |
24 | );
25 | };
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/114x114-roundel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/114x114-roundel.png
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/114x114.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/114x114.png
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/120x120.png
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/144x144.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/144x144.png
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/152x152-roundel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/152x152-roundel.png
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/152x152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/152x152.png
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/32x32-dev.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/32x32-dev.ico
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/32x32.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/32x32.ico
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/57x57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/57x57.png
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/brand/favicons/72x72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/guardian/source/d84c25d67ed51545994f53986eb4487d35c1aab4/packages/@guardian/source-react-components/src/brand/favicons/72x72.png
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/checkbox/LabelText.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import type { ReactNode } from 'react';
3 | import type { Theme } from '../@types/Theme';
4 | import { labelText, labelTextWithSupportingText } from './styles';
5 |
6 | export const LabelText = ({
7 | hasSupportingText,
8 | children,
9 | }: {
10 | hasSupportingText?: boolean;
11 | children: ReactNode;
12 | }): EmotionJSX.Element => {
13 | return (
14 | [
16 | labelText(theme.checkbox),
17 | hasSupportingText ? labelTextWithSupportingText : '',
18 | ]}
19 | >
20 | {children}
21 |
22 | );
23 | };
24 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/checkbox/SupportingText.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import type { ReactNode } from 'react';
3 | import type { Theme } from '../@types/Theme';
4 | import { supportingText } from './styles';
5 |
6 | export const SupportingText = ({
7 | children,
8 | }: {
9 | children: ReactNode;
10 | }): EmotionJSX.Element => {
11 | return (
12 | supportingText(theme.checkbox)}>{children}
13 | );
14 | };
15 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/checkbox/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 | import { labelThemeBrand, labelThemeDefault } from '../label/theme';
3 | import {
4 | userFeedbackThemeBrand,
5 | userFeedbackThemeDefault,
6 | } from '../user-feedback/theme';
7 |
8 | export const checkboxThemeDefault = {
9 | checkbox: {
10 | border: palette.neutral[46],
11 | borderHover: palette.brand[500],
12 | borderChecked: palette.brand[500],
13 | borderError: palette.error[400],
14 | backgroundChecked: palette.brand[500],
15 | textLabel: palette.neutral[7],
16 | textLabelSupporting: palette.neutral[46],
17 | textIndeterminate: palette.neutral[46],
18 | },
19 | ...userFeedbackThemeDefault,
20 | ...labelThemeDefault,
21 | };
22 |
23 | export const checkboxThemeBrand = {
24 | checkbox: {
25 | border: palette.brand[800],
26 | borderHover: palette.neutral[100],
27 | borderChecked: palette.neutral[100],
28 | borderError: palette.error[500],
29 | backgroundChecked: palette.neutral[100],
30 | textLabel: palette.neutral[100],
31 | textLabelSupporting: palette.brand[800],
32 | textIndeterminate: palette.brand[800],
33 | },
34 | ...userFeedbackThemeBrand,
35 | ...labelThemeBrand,
36 | };
37 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/choice-card/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 | import { userFeedbackThemeDefault } from '../user-feedback/theme';
3 |
4 | export const choiceCardThemeDefault = {
5 | choiceCard: {
6 | textLabel: palette.neutral[46],
7 | textLabelSupporting: palette.neutral[46],
8 | textGroupLabel: palette.neutral[7],
9 | textGroupLabelSupporting: palette.neutral[46],
10 | border: palette.neutral[46],
11 | textChecked: palette.brand[400],
12 | backgroundChecked: '#E3F6FF',
13 | backgroundTick: palette.brand[500],
14 | borderChecked: palette.brand[500],
15 | textHover: palette.brand[400],
16 | borderHover: palette.brand[500],
17 | textError: palette.error[400],
18 | borderError: palette.error[400],
19 | },
20 | ...userFeedbackThemeDefault,
21 | };
22 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/footer/BackToTop.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import { BackToTop } from './BackToTop';
3 |
4 | export default {
5 | component: BackToTop,
6 | title: 'Packages/source-react-components/BackToTop',
7 | };
8 |
9 | const Template: Story = () => BackToTop;
10 |
11 | export const Default = Template.bind({});
12 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/footer/BackToTop.tsx:
--------------------------------------------------------------------------------
1 | import { SvgChevronUpSingle } from '../../vendor/icons/SvgChevronUpSingle';
2 | import type { Theme } from '../@types/Theme';
3 | import { backToTop, backToTopIcon } from './styles';
4 |
5 | export const BackToTop = (
6 | backToTop(theme.footer)}>
7 | Back to top
8 | backToTopIcon(theme.footer)}>
9 |
10 |
11 |
12 | );
13 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/footer/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 |
3 | export const footerThemeBrand = {
4 | footer: {
5 | border: palette.brand[600],
6 | background: palette.brand[400],
7 | text: palette.neutral[100],
8 | anchor: palette.neutral[100],
9 | anchorHover: palette.brandAlt[400],
10 | },
11 | };
12 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/inline/Inline.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import type { HTMLAttributes } from 'react';
3 | import type { Props } from '../@types/Props';
4 | import { inline, inlineSpace } from './styles';
5 | import type { InlineSpace } from './types';
6 |
7 | export interface InlineProps extends HTMLAttributes, Props {
8 | /**
9 | * [Units of space](https://www.theguardian.design/2a1e5182b/p/449bd5-space) between inline items (one unit is 4px).
10 | */
11 | space?: InlineSpace;
12 | }
13 |
14 | /**
15 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-inline) •
16 | * [Design System](https://theguardian.design/2a1e5182b/p/99f3c1-inline) •
17 | * [GitHub](https://github.com/guardian/source/tree/main/packages/@guardian/source-react-components/src/inline/Inline.tsx) •
18 | * [NPM](https://www.npmjs.com/package/@guardian/source-react-components)
19 | *
20 | * `Inline` components will be laid out one next to the other.
21 | */
22 | export const Inline = ({
23 | cssOverrides,
24 | children,
25 | space,
26 | ...props
27 | }: InlineProps): EmotionJSX.Element => {
28 | return (
29 |
33 | {children}
34 |
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/inline/styles.ts:
--------------------------------------------------------------------------------
1 | import type { SerializedStyles } from '@emotion/react';
2 | import { css } from '@emotion/react';
3 | import { space } from '@guardian/source-foundations';
4 | import type { InlineSpace } from './types';
5 |
6 | export const inline = css`
7 | display: flex;
8 | flex-wrap: wrap;
9 | `;
10 |
11 | const inlineSpaceStyle = (number: InlineSpace): SerializedStyles => css`
12 | margin-left: -${space[number]}px;
13 | & > * {
14 | margin-left: ${space[number]}px;
15 | margin-bottom: ${space[number]}px;
16 | }
17 | `;
18 |
19 | export const inlineSpace: {
20 | 1: SerializedStyles;
21 | 2: SerializedStyles;
22 | 3: SerializedStyles;
23 | 4: SerializedStyles;
24 | 5: SerializedStyles;
25 | 6: SerializedStyles;
26 | 9: SerializedStyles;
27 | 12: SerializedStyles;
28 | 24: SerializedStyles;
29 | } = {
30 | 1: inlineSpaceStyle(1),
31 | 2: inlineSpaceStyle(2),
32 | 3: inlineSpaceStyle(3),
33 | 4: inlineSpaceStyle(4),
34 | 5: inlineSpaceStyle(5),
35 | 6: inlineSpaceStyle(6),
36 | 9: inlineSpaceStyle(9),
37 | 12: inlineSpaceStyle(12),
38 | 24: inlineSpaceStyle(24),
39 | };
40 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/inline/types.ts:
--------------------------------------------------------------------------------
1 | export type InlineSpace = 1 | 2 | 3 | 4 | 5 | 6 | 9 | 12 | 24;
2 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/label/SupportingText.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
3 | import { visuallyHidden as _visuallyHidden } from '@guardian/source-foundations';
4 | import type { ReactNode } from 'react';
5 | import type { Theme } from '../@types/Theme';
6 | import { supportingText } from './styles';
7 |
8 | const visuallyHidden = css`
9 | ${_visuallyHidden}
10 | `;
11 |
12 | export const SupportingText = ({
13 | hideLabel,
14 | children,
15 | }: {
16 | hideLabel?: boolean;
17 | children: ReactNode;
18 | }): EmotionJSX.Element => {
19 | return (
20 | [
22 | supportingText(theme.label),
23 | hideLabel ? visuallyHidden : '',
24 | ]}
25 | >
26 | {children}
27 |
28 | );
29 | };
30 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/label/Text.tsx:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
3 | import { visuallyHidden as _visuallyHidden } from '@guardian/source-foundations';
4 | import type { Theme } from '../@types/Theme';
5 | import { labelText, optionalText } from './styles';
6 | import type { LabelProps } from './types';
7 |
8 | const visuallyHidden = css`
9 | ${_visuallyHidden}
10 | `;
11 |
12 | export const Text = ({
13 | text,
14 | optional,
15 | hideLabel,
16 | }: LabelProps): EmotionJSX.Element => (
17 | [
19 | labelText(theme.label),
20 | hideLabel ? visuallyHidden : '',
21 | ]}
22 | >
23 | {text}{' '}
24 | {optional ? (
25 | optionalText(theme.label)}>Optional
26 | ) : (
27 | ''
28 | )}
29 |
30 | );
31 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/label/styles.ts:
--------------------------------------------------------------------------------
1 | import type { SerializedStyles } from '@emotion/react';
2 | import { css } from '@emotion/react';
3 | import { resets, textSans } from '@guardian/source-foundations';
4 | import { labelThemeDefault } from './theme';
5 |
6 | export const legend = css`
7 | ${resets.legend};
8 | `;
9 |
10 | export const labelText = (
11 | label = labelThemeDefault.label,
12 | ): SerializedStyles => css`
13 | ${textSans.medium({ fontWeight: 'bold' })};
14 | color: ${label.textLabel};
15 | `;
16 |
17 | export const optionalText = (
18 | label = labelThemeDefault.label,
19 | ): SerializedStyles => css`
20 | ${textSans.small()};
21 | color: ${label.textOptional};
22 | font-style: italic;
23 | `;
24 |
25 | export const supportingText = (
26 | label = labelThemeDefault.label,
27 | ): SerializedStyles => css`
28 | ${textSans.small()};
29 | color: ${label.textSupporting};
30 | margin: 2px 0 0;
31 | `;
32 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/label/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 |
3 | export const labelThemeDefault = {
4 | label: {
5 | textLabel: palette.neutral[7],
6 | textOptional: palette.neutral[46],
7 | textSupporting: palette.neutral[46],
8 | textError: palette.error[400],
9 | textSuccess: palette.success[400],
10 | },
11 | };
12 |
13 | export const labelThemeBrand = {
14 | label: {
15 | textLabel: palette.neutral[100],
16 | textOptional: palette.brand[800],
17 | textSupporting: palette.brand[800],
18 | textError: palette.error[500],
19 | textSuccess: palette.success[500],
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/label/types.ts:
--------------------------------------------------------------------------------
1 | import type { SerializedStyles } from '@emotion/react';
2 | import type { HTMLAttributes, LabelHTMLAttributes, ReactNode } from 'react';
3 | import type { Props } from '../@types/Props';
4 |
5 | export interface LabelProps
6 | extends LabelHTMLAttributes,
7 | Props {
8 | /**
9 | * The label text
10 | */
11 | text: string;
12 | /**
13 | * Additional text or component that appears below the label
14 | */
15 | supporting?: string;
16 | /**
17 | * Adds the word "Optional" after the label
18 | */
19 | optional?: boolean;
20 | /**
21 | * Visually hides the label
22 | */
23 | hideLabel?: boolean;
24 | cssOverrides?: SerializedStyles | SerializedStyles[];
25 | children?: ReactNode;
26 | }
27 |
28 | export interface LegendProps extends HTMLAttributes, Props {
29 | /**
30 | * The label text
31 | */
32 | text: string;
33 | /**
34 | * Additional text or component that appears below the label
35 | */
36 | supporting?: string | JSX.Element;
37 | /**
38 | * Adds the word "Optional" after the label
39 | */
40 | optional?: boolean;
41 | /**
42 | * Visually hides the label
43 | */
44 | hideLabel?: boolean;
45 | cssOverrides?: SerializedStyles | SerializedStyles[];
46 | }
47 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/link/shared.tsx:
--------------------------------------------------------------------------------
1 | import type { ReactElement, ReactNode } from 'react';
2 | import { cloneElement, Fragment } from 'react';
3 | import type { IconSide } from './types';
4 |
5 | export const linkContents = ({
6 | children,
7 | iconSvg,
8 | iconSide,
9 | }: {
10 | children: ReactNode;
11 | iconSvg?: ReactElement;
12 | iconSide: IconSide;
13 | }): ReactNode[] => {
14 | // a bit of underlined space; the icon sits on top
15 | const spacer = (
16 |
17 | );
18 | const linkContents = [children];
19 |
20 | if (iconSvg) {
21 | if (iconSide === 'left') {
22 | linkContents.unshift(spacer, cloneElement(iconSvg, { key: 'svg' }));
23 | } else {
24 | linkContents.push(spacer, cloneElement(iconSvg, { key: 'svg' }));
25 | }
26 | }
27 |
28 | return linkContents;
29 | };
30 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/link/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 |
3 | export type LinkTheme = {
4 | textPrimary: string;
5 | textPrimaryHover: string;
6 | textSecondary?: string;
7 | textSecondaryHover?: string;
8 | };
9 |
10 | export const linkThemeDefault: { link: LinkTheme } = {
11 | link: {
12 | textPrimary: palette.brand[500],
13 | textPrimaryHover: palette.brand[500],
14 | textSecondary: palette.neutral[7],
15 | textSecondaryHover: palette.neutral[7],
16 | },
17 | };
18 |
19 | export const linkThemeBrand: { link: LinkTheme } = {
20 | link: {
21 | textPrimary: palette.neutral[100],
22 | textPrimaryHover: palette.neutral[100],
23 | },
24 | };
25 |
26 | export const linkThemeBrandAlt: { link: LinkTheme } = {
27 | link: {
28 | textPrimary: palette.neutral[7],
29 | textPrimaryHover: palette.neutral[7],
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/link/types.ts:
--------------------------------------------------------------------------------
1 | import type { ReactElement, ReactNode } from 'react';
2 | import type { Props } from '../@types/Props';
3 |
4 | export type LinkPriority = 'primary' | 'secondary';
5 |
6 | export type IconSide = 'left' | 'right';
7 |
8 | export interface SharedLinkProps extends Props {
9 | /**
10 | * Informs users of how important a link is
11 | */
12 | priority?: LinkPriority;
13 | /**
14 | * Whether link is subdued (no underline)
15 | *
16 | * @deprecated Subdued styling has been removed and no longer gets applied
17 | */
18 | subdued?: boolean;
19 | /**
20 | * An icon that appears in the link, alongside text
21 | */
22 | icon?: ReactElement;
23 | /**
24 | * The side of the link on which the icon appears
25 | */
26 | iconSide?: IconSide;
27 | children?: ReactNode;
28 | }
29 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/radio/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 | import { labelThemeBrand, labelThemeDefault } from '../label/theme';
3 | import {
4 | userFeedbackThemeBrand,
5 | userFeedbackThemeDefault,
6 | } from '../user-feedback/theme';
7 |
8 | export const radioThemeDefault = {
9 | radio: {
10 | borderHover: palette.focus[400],
11 | border: palette.neutral[60],
12 | backgroundChecked: palette.focus[400],
13 | textLabel: palette.neutral[7],
14 | textLabelSupporting: palette.neutral[46],
15 | borderError: palette.error[400],
16 | },
17 | ...labelThemeDefault,
18 | ...userFeedbackThemeDefault,
19 | };
20 |
21 | export const radioThemeBrand = {
22 | radio: {
23 | borderHover: palette.neutral[100],
24 | border: palette.brand[800],
25 | backgroundChecked: palette.neutral[100],
26 | textLabel: palette.neutral[100],
27 | textLabelSupporting: palette.brand[800],
28 | borderError: palette.error[500],
29 | },
30 | ...labelThemeBrand,
31 | ...userFeedbackThemeBrand,
32 | };
33 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/select/Option.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import type { OptionHTMLAttributes } from 'react';
3 | import type { Props } from '../@types/Props';
4 |
5 | export interface OptionProps
6 | extends OptionHTMLAttributes,
7 | Props {
8 | children: string;
9 | }
10 |
11 | export const Option = ({
12 | cssOverrides,
13 | children,
14 | ...props
15 | }: OptionProps): EmotionJSX.Element => {
16 | return (
17 |
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/select/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 | import { userFeedbackThemeDefault } from '../user-feedback/theme';
3 |
4 | export const selectThemeDefault = {
5 | select: {
6 | textUserInput: palette.neutral[7],
7 | textLabel: palette.neutral[7],
8 | textLabelOptional: palette.neutral[46],
9 | textLabelSupporting: palette.neutral[46],
10 | textError: palette.neutral[7],
11 | textSuccess: palette.success[400],
12 | backgroundInput: palette.neutral[100],
13 | border: palette.neutral[46],
14 | borderActive: palette.focus[400],
15 | borderError: palette.error[400],
16 | borderSuccess: palette.success[400],
17 | },
18 | ...userFeedbackThemeDefault,
19 | };
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/stack/Stack.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import type { HTMLAttributes } from 'react';
3 | import type { Props } from '../@types/Props';
4 | import { stack, stackSpace } from './styles';
5 |
6 | export type StackSpace = 1 | 2 | 3 | 4 | 5 | 6 | 9 | 12 | 24;
7 |
8 | export interface StackProps extends HTMLAttributes, Props {
9 | /**
10 | * [Units of space](https://www.theguardian.design/2a1e5182b/p/449bd5-space) between inline items (one unit is 4px).
11 | */
12 | space?: StackSpace;
13 | }
14 |
15 | /**
16 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-stack) •
17 | * [Design System](https://theguardian.design/2a1e5182b/p/827581-stack) •
18 | * [GitHub](https://github.com/guardian/source/tree/main/packages/@guardian/source-react-components/src/stack/Stack.tsx) •
19 | * [NPM](https://www.npmjs.com/package/@guardian/source-react-components)
20 | *
21 | * `Stack` components will be stacked one on top of the other.
22 | */
23 | export const Stack = ({
24 | cssOverrides,
25 | children,
26 | space,
27 | ...props
28 | }: StackProps): EmotionJSX.Element => {
29 | return (
30 |
31 | {children}
32 |
33 | );
34 | };
35 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/stack/styles.ts:
--------------------------------------------------------------------------------
1 | import type { SerializedStyles } from '@emotion/react';
2 | import { css } from '@emotion/react';
3 | import { space } from '@guardian/source-foundations';
4 | import type { StackSpace } from './Stack';
5 |
6 | export const stack = css`
7 | & > * {
8 | width: 100%;
9 | }
10 | `;
11 |
12 | const stackSpaceStyle = (number: StackSpace): SerializedStyles => css`
13 | & > * + * {
14 | margin-top: ${space[number]}px;
15 | }
16 | `;
17 |
18 | export const stackSpace: {
19 | 1: SerializedStyles;
20 | 2: SerializedStyles;
21 | 3: SerializedStyles;
22 | 4: SerializedStyles;
23 | 5: SerializedStyles;
24 | 6: SerializedStyles;
25 | 9: SerializedStyles;
26 | 12: SerializedStyles;
27 | 24: SerializedStyles;
28 | } = {
29 | 1: stackSpaceStyle(1),
30 | 2: stackSpaceStyle(2),
31 | 3: stackSpaceStyle(3),
32 | 4: stackSpaceStyle(4),
33 | 5: stackSpaceStyle(5),
34 | 6: stackSpaceStyle(6),
35 | 9: stackSpaceStyle(9),
36 | 12: stackSpaceStyle(12),
37 | 24: stackSpaceStyle(24),
38 | };
39 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/text-input/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 | import { userFeedbackThemeDefault } from '../user-feedback/theme';
3 |
4 | export const textInputThemeDefault = {
5 | textInput: {
6 | textUserInput: palette.neutral[7],
7 | textLabel: palette.neutral[7],
8 | textLabelOptional: palette.neutral[46],
9 | textLabelSupporting: palette.neutral[46],
10 | textError: palette.neutral[7],
11 | textSuccess: palette.success[400],
12 | backgroundInput: palette.neutral[100],
13 | border: palette.neutral[46],
14 | borderActive: palette.focus[400],
15 | borderError: palette.error[400],
16 | borderSuccess: palette.success[400],
17 | },
18 | ...userFeedbackThemeDefault,
19 | };
20 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/tiles/types.ts:
--------------------------------------------------------------------------------
1 | export type Columns = 2 | 3 | 4 | 5;
2 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/user-feedback/InlineError.tsx:
--------------------------------------------------------------------------------
1 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
2 | import { SvgAlertTriangle } from '../../vendor/icons/SvgAlertTriangle';
3 | import type { Theme } from '../@types/Theme';
4 | import { inlineError } from './styles';
5 | import type { UserFeedbackProps } from './types';
6 |
7 | /**
8 | * [Storybook](https://guardian.github.io/source/?path=/docs/packages-source-react-components-inlineerror--playground) •
9 | * [Design System](https://theguardian.design/2a1e5182b/p/108ed3-user-feedback/b/3803b4) •
10 | * [GitHub](https://github.com/guardian/source/tree/main/packages/@guardian/source-react-components/src/user-feedback/InlineError.tsx) •
11 | * [NPM](https://www.npmjs.com/package/@guardian/source-react-components-feedback)
12 | *
13 | * Used to inform the user when a validation has failed or user error has occurred. These messages indicate what went wrong and how to fix it.
14 | *
15 | * The following themes are supported: `default`, `brand`
16 | */
17 | export const InlineError = ({
18 | children,
19 | cssOverrides,
20 | ...props
21 | }: UserFeedbackProps): EmotionJSX.Element => (
22 | [inlineError(theme.userFeedback), cssOverrides]}
24 | role="alert"
25 | {...props}
26 | >
27 |
28 | {children}
29 |
30 | );
31 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/user-feedback/InlineSuccess.stories.tsx:
--------------------------------------------------------------------------------
1 | import type { Story } from '@storybook/react';
2 | import { InlineSuccess } from './InlineSuccess';
3 | import { userFeedbackThemeBrand } from './theme';
4 | import type { UserFeedbackProps } from './types';
5 |
6 | export default {
7 | title: 'Packages/source-react-components/InlineSuccess',
8 | component: InlineSuccess,
9 | };
10 |
11 | const Template: Story = (args: UserFeedbackProps) => (
12 | Your voucher code is valid
13 | );
14 |
15 | export const InlineSuccessDefaultTheme = Template.bind({});
16 |
17 | // *****************************************************************************
18 |
19 | export const InlineSuccessBrandTheme = Template.bind({});
20 | InlineSuccessBrandTheme.parameters = {
21 | backgrounds: {
22 | default: 'brandBackground.primary',
23 | },
24 | theme: userFeedbackThemeBrand,
25 | };
26 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/user-feedback/styles.ts:
--------------------------------------------------------------------------------
1 | import type { SerializedStyles } from '@emotion/react';
2 | import { css } from '@emotion/react';
3 | import { remHeight, remWidth, textSans } from '@guardian/source-foundations';
4 | import { userFeedbackThemeDefault } from './theme';
5 |
6 | const inlineMessage = css`
7 | display: flex;
8 | align-items: flex-start;
9 | ${textSans.medium()};
10 |
11 | svg {
12 | fill: currentColor;
13 | /* we don't want the SVG to change size depending on available space */
14 | flex: none;
15 | width: ${remWidth.iconMedium}rem;
16 | height: ${remHeight.iconMedium}rem;
17 |
18 | /*
19 | a visual kick to vertically align the icon with the top row of text
20 | and horizontally pull it to the beginning of the row
21 | */
22 | transform: translate(-4px, -3px);
23 | }
24 | `;
25 |
26 | export const inlineError = (
27 | userFeedback = userFeedbackThemeDefault.userFeedback,
28 | ): SerializedStyles => css`
29 | ${inlineMessage};
30 | color: ${userFeedback.textError};
31 | `;
32 |
33 | export const inlineSuccess = (
34 | userFeedback = userFeedbackThemeDefault.userFeedback,
35 | ): SerializedStyles => css`
36 | ${inlineMessage};
37 | color: ${userFeedback.textSuccess};
38 | `;
39 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/user-feedback/theme.ts:
--------------------------------------------------------------------------------
1 | import { palette } from '@guardian/source-foundations';
2 |
3 | export const userFeedbackThemeDefault = {
4 | userFeedback: {
5 | textSuccess: palette.success[400],
6 | textError: palette.error[400],
7 | },
8 | };
9 |
10 | export const userFeedbackThemeBrand = {
11 | userFeedback: {
12 | textSuccess: palette.success[500],
13 | textError: palette.error[500],
14 | },
15 | };
16 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/src/user-feedback/types.ts:
--------------------------------------------------------------------------------
1 | import type { HTMLAttributes, ReactNode } from 'react';
2 | import type { Props } from '../@types/Props';
3 |
4 | export interface UserFeedbackProps
5 | extends Props,
6 | HTMLAttributes {
7 | children: ReactNode;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/README.md:
--------------------------------------------------------------------------------
1 | # Icons
2 |
3 | **The contents of this directory are created automatically. Any edits will be
4 | overwritten sooner or later.**
5 |
6 | The SVGs for these icons are automatically pulled in from the [source design file in
7 | Figma](https://www.figma.com/file/Ai7AELHC6KCz38qKZkvuHo/%E2%97%90-Icons?node-id=55%3A2)
8 | using the create-icons script via the Figma API:
9 |
10 | ```sh
11 | yarn workspace @guardian/source-react-components create-icons
12 | ```
13 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowContract.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowContract = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Collapse
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowDownStraight.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowDownStraight = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Arrow down
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowExpand.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowExpand = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Expand
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowLeftStraight.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowLeftStraight = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Arrow left
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowOutdent.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowOutdent = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Up left arrow
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowPopOut.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowPopOut = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Pop out
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowRightStraight.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowRightStraight = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Arrow right
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowUpAndDownSmall.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowUpAndDownSmall = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Up and down arrow
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowUpStraight.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowUpStraight = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Arrow up
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgArrowUpStraightSmall.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgArrowUpStraightSmall = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Arrow up
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgAsterisk.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgAsterisk = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Asterisk
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgAudioMute.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgAudioMute = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Sound off
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgBookMark.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgBookMark = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Bookmark
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgCamera.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgCamera = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Camera
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgCheckmark.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgCheckmark = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Checkmark
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronDownDouble.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronDownDouble = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Double chevron down
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronDownSingle.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronDownSingle = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Expand to show more
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronDownSingleXsmall.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronDownSingleXsmall = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Expand to show more
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronLeftDouble.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronLeftDouble = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Double chevron left
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronLeftSingle.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronLeftSingle = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Chevron left
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronRightDouble.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronRightDouble = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Double chevron right
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronRightSingle.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronRightSingle = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Chevron right
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronUpDouble.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronUpDouble = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Double chevron up
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgChevronUpSingle.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgChevronUpSingle = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Collapse to show less
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgClock.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgClock = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Clock
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgClockBaselineSmall.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgClockBaselineSmall = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Clock
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgCross.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgCross = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Close
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgCrosswords.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgCrosswords = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Crosswords
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgDocument.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgDocument = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Document
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgDownload.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgDownload = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Download
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgDragHandle.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgDragHandle = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Drag
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgEnvelope.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
20 | );
21 |
22 | export const SvgEnvelope = ({
23 | size,
24 | isAnnouncedByScreenReader = false,
25 | }: IconProps): EmotionJSX.Element => (
26 | <>
27 |
28 | {isAnnouncedByScreenReader ? (
29 |
34 | Email
35 |
36 | ) : (
37 | ''
38 | )}
39 | >
40 | );
41 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgExternal.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgExternal = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | External link
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgFacebook.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgFacebook = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Facebook logo
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgFilter.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgFilter = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Filter
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgGift.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
19 | );
20 |
21 | export const SvgGift = ({
22 | size,
23 | isAnnouncedByScreenReader = false,
24 | }: IconProps): EmotionJSX.Element => (
25 | <>
26 |
27 | {isAnnouncedByScreenReader ? (
28 |
33 | Gift
34 |
35 | ) : (
36 | ''
37 | )}
38 | >
39 | );
40 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgGps.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgGps = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Location
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgHouse.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgHouse = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Home
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgHousePlus.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgHousePlus = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Add to home
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgIndent.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgIndent = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Indent
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgMediaControlsBack.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgMediaControlsBack = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Rewind
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgMediaControlsForward.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgMediaControlsForward = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Fast forward
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgMediaControlsPause.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgMediaControlsPause = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Pause
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgMediaControlsPlay.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgMediaControlsPlay = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Play
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgMediaControlsStop.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgMediaControlsStop = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Stop
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgMenu.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgMenu = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Menu
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgMinus.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
19 | );
20 |
21 | export const SvgMinus = ({
22 | size,
23 | isAnnouncedByScreenReader = false,
24 | }: IconProps): EmotionJSX.Element => (
25 | <>
26 |
27 | {isAnnouncedByScreenReader ? (
28 |
33 | Minus sign
34 |
35 | ) : (
36 | ''
37 | )}
38 | >
39 | );
40 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgPinned.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
19 | );
20 |
21 | export const SvgPinned = ({
22 | size,
23 | isAnnouncedByScreenReader = false,
24 | }: IconProps): EmotionJSX.Element => (
25 | <>
26 |
27 | {isAnnouncedByScreenReader ? (
28 |
33 | Pinned
34 |
35 | ) : (
36 | ''
37 | )}
38 | >
39 | );
40 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgPlus.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgPlus = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Plus sign
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgQuote.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgQuote = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Quote
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgSpeechBubble.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgSpeechBubble = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Comments
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgSpeechBubblePlus.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgSpeechBubblePlus = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Add comment
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgStar.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgStar = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Star
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgTextLarge.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgTextLarge = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Large text
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgTextSmall.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgTextSmall = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Small text
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgTickRound.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgTickRound = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Ticked
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgUpload.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgUpload = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Upload
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/packages/@guardian/source-react-components/vendor/icons/SvgVideo.tsx:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT
2 | // this file is auto-generated by packages/@guardian/source-react-components/scripts/create-icons/index.ts
3 | import { css } from '@emotion/react';
4 | import type { EmotionJSX } from '@emotion/react/types/jsx-namespace';
5 | import { iconSize, visuallyHidden } from '@guardian/source-foundations';
6 | import type { IconProps } from '../../src/@types/Icons';
7 |
8 | const Svg = ({ size }: IconProps): EmotionJSX.Element => (
9 |
23 | );
24 |
25 | export const SvgVideo = ({
26 | size,
27 | isAnnouncedByScreenReader = false,
28 | }: IconProps): EmotionJSX.Element => (
29 | <>
30 |
31 | {isAnnouncedByScreenReader ? (
32 |
37 | Video
38 |
39 | ) : (
40 | ''
41 | )}
42 | >
43 | );
44 |
--------------------------------------------------------------------------------
/scripts/README.md:
--------------------------------------------------------------------------------
1 | # Scripts
2 |
3 | This directory provides a series of scripts that are useful to the maintainers of Source.
4 |
5 | ## Running
6 |
7 | Scripts that are intended to be run directly all contain aliases in at least one `package.json`.
8 |
9 | For example, the `build-src.ts` script can be run using `yarn build:src` from the root directory.
10 |
11 | Some of the scripts in nested directories may need to be run via the workspace command (`yarn workspace $WORSPACE $COMMAND`). These cases will be documented in the README within that directory.
12 |
13 | Some scripts are not intended to be run directly, and are instead consumed by other scripts within this directory. If you do have a need to run them directly, you can do so using `ts-node`. For example, `yarn ts-node ./scripts/paths`. As these scripts are designed to be consumed by others, this is unlikely to yield any interesting behaviour but may be useful for debugging if you are developing on one or more of these files.
14 |
--------------------------------------------------------------------------------
/stylelint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | processors: ['stylelint-processor-styled-components'],
3 | extends: [
4 | 'stylelint-config-recommended',
5 | 'stylelint-config-styled-components',
6 | ],
7 | rules: {
8 | 'no-descending-specificity': null,
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@guardian/tsconfig/tsconfig.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "declaration": true,
6 | "declarationMap": true,
7 | "forceConsistentCasingInFileNames": true,
8 | "jsx": "react-jsx",
9 | "jsxImportSource": "@emotion/react",
10 | "noEmit": true,
11 | "paths": {
12 | "@guardian/source-foundations": [
13 | "packages/@guardian/source-foundations/src/index"
14 | ],
15 | "@guardian/source-react-components": [
16 | "packages/@guardian/source-react-components/src/index"
17 | ],
18 | "@guardian/source-react-components-development-kitchen": [
19 | "packages/@guardian/source-react-components-development-kitchen/src/index"
20 | ],
21 | "@guardian/eslint-plugin-source-foundations": [
22 | "packages/@guardian/eslint-plugin-source-foundations/src/index"
23 | ],
24 | "@guardian/eslint-plugin-source-react-components": [
25 | "packages/@guardian/eslint-plugin-source-react-components/src/index"
26 | ]
27 | },
28 | "sourceMap": true
29 | },
30 | "ts-node": {
31 | "compilerOptions": {
32 | "module": "CommonJS"
33 | }
34 | },
35 | "include": ["packages", "lib", "scripts"],
36 | "exclude": ["node_modules", "dist"]
37 | }
38 |
--------------------------------------------------------------------------------