diff --git a/packages/css/src/components/component/README.md b/packages/css/src/components/component/README.md new file mode 100644 index 0000000000..c9cb088a06 --- /dev/null +++ b/packages/css/src/components/component/README.md @@ -0,0 +1,9 @@ + + +# Component Name + +(Rationale) +Describes the essential purpose of the component in 1 or 2 sentences. +From the perspective of the component – mentions its characteristics only, nothing about usage or guidelines. + +Lorem ipsum diff --git a/packages/react/src/Component/Component.tsx b/packages/react/src/Component/Component.tsx new file mode 100644 index 0000000000..5873610a13 --- /dev/null +++ b/packages/react/src/Component/Component.tsx @@ -0,0 +1,24 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +import clsx from 'clsx' +import { forwardRef } from 'react' +import type { ForwardedRef, HTMLAttributes, PropsWithChildren } from 'react' +import { Paragraph } from '../Paragraph' + +export type ComponentProps = { + /** The size of the text for this component. */ + size?: 'small' | 'large' +} & PropsWithChildren> + +export const Component = forwardRef( + ({ children, className, size, ...restProps }: ComponentProps, ref: ForwardedRef) => ( + + {children} + + ), +) + +Component.displayName = 'Component' diff --git a/packages/react/src/Component/index.ts b/packages/react/src/Component/index.ts new file mode 100644 index 0000000000..670c94e6b5 --- /dev/null +++ b/packages/react/src/Component/index.ts @@ -0,0 +1,2 @@ +export { Component } from './Component' +export type { ComponentProps } from './Component' diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index a71afe61bc..019aad72f4 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -4,6 +4,7 @@ */ /* Append here */ +export * from './Component' export * from './Avatar' export * from './FormFieldCharacterCounter' export * from './DescriptionList' diff --git a/proprietary/tokens/src/components/ams/alert.tokens.json b/proprietary/tokens/src/components/ams/alert.tokens.json index 9ba890705c..8b87daeaab 100644 --- a/proprietary/tokens/src/components/ams/alert.tokens.json +++ b/proprietary/tokens/src/components/ams/alert.tokens.json @@ -1,8 +1,8 @@ { "ams": { "alert": { - "border-width": { "value": "{ams.border.width.xl}" }, "border-style": { "value": "solid" }, + "border-width": { "value": "{ams.border.width.xl}" }, "gap": { "value": "1rem" }, "padding-block": { "value": "{ams.space.inside.md}" }, "padding-inline": { "value": "{ams.space.inside.lg}" }, diff --git a/storybook/config/preview-body.html b/storybook/config/preview-body.html index d655261501..a3203c338e 100644 --- a/storybook/config/preview-body.html +++ b/storybook/config/preview-body.html @@ -36,4 +36,46 @@ margin: -16px; /* stylelint-disable-line */ padding: 16px; /* stylelint-disable-line */ } + + .ams-docs-border-width-4 { + background-color: var(--ams-color-primary-black); + height: 0.75rem; + width: 4px; + } + + [class|="ams-docs-color"] { + border: 1px solid rgba(0, 0, 0, 0.125); + height: 0.75rem; + width: 0.75rem; + } + + .ams-docs-color-dark-green { + background-color: var(--ams-color-dark-green); + } + + .ams-docs-color-primary-blue { + background-color: var(--ams-color-primary-blue); + } + + .ams-docs-color-primary-red { + background-color: var(--ams-color-primary-red); + } + + .ams-docs-space-width-0\.75rem { + height: 0.5rem; + outline: 1px dashed var(--ams-color-neutral-grey2); + width: 0.75rem; + } + + .ams-docs-space-width-1rem { + height: 0.5rem; + outline: 1px dashed var(--ams-color-neutral-grey2); + width: 1rem; + } + + .ams-docs-space-width-1\.5rem { + height: 0.5rem; + outline: 1px dashed var(--ams-color-neutral-grey2); + width: 1.5rem; + } diff --git a/storybook/src/components/Component/Component.docs.mdx b/storybook/src/components/Component/Component.docs.mdx new file mode 100644 index 0000000000..63c6b70b07 --- /dev/null +++ b/storybook/src/components/Component/Component.docs.mdx @@ -0,0 +1,152 @@ +import { Controls, Markdown, Meta, Primary } from "@storybook/blocks"; +import * as ComponentStories from "./Component.stories.tsx"; +import README from "../../../../packages/css/src/components/component/README.md?raw"; + + + +{README} + + + + + +## 1. How to use + +### 1.1. When to use + +Specify scenarios when the component should be used. + +### 1.2. When not to use + +Highlight context in which the component may not be suitable and suggest alternatives. + +### 1.3. Content + +Instruct what to consider when writing content for this component. + +### 1.4. Accessibility + +TODO + +- [WCAG 1.3.1](https://www.w3.org/TR/WCAG21/#info-and-relationships): Blocks that look like a paragraph are also recognized by a computer as a paragraph. +- [WCAG 1.3.5](https://www.w3.org/WAI/WCAG21/Understanding/identify-input-purpose.html): It is clear for both users and programmatically what the purpose of a form field is. +- [WCAG 1.4.3](https://www.w3.org/TR/WCAG21/#contrast-minimum): The contrast of black text on a white background is high enough. + +Checkbox is an interactive element; therefore, [the general requirements and guidelines for interactive elements](/docs/docs-design-guidelines-interactive-elements--docs) apply. + +### 1.5. Layout + +E.g. information on responsive design, how to place things on the grid etc. + +### 1.6. Performance + +Discuss strategies for reducing rendering time, improving load times, and minimizing resource usage. + +### 1.7. Compatibility + +Specify the browsers and platforms where the component has been tested and confirmed to work correctly. +Highlight any known issues or limitations on specific devices or environments. + +### 1.8. Privacy + +Outline security considerations relevant to the component, such as data validation, input sanitization, and protection against common vulnerabilities (e.g., XSS, CSRF). +Offer guidance on implementing secure coding practices when using the component. + +## 2. Additional Examples + +Provide multiple examples illustrating different use cases and variations of the component. +If the component has subcomponents, add a default example for each and include the controls as well. + +### Subcomponent name + + + + + +### Title of the example + + + +### Title of the example + + + +## 3. Design Choices + +### 3.1. Visual + +Explains the choices that have been made in the visual design of the component. + +### 3.2. Interaction + +Explains the choices that have been made in the interaction design of the component. + +### 3.3. Motion + +Explains the choices that have been made in the motion design of the component. + +### 3.4. Figma + +(Figma frame here?) + +### 3.5 Design tokens + +The design has been encoded into the following tokens: + +| Name | Value | Preview | +| :------------------------------- | :----------------------- | :---------------------------------------------- | +| `ams-alert-border-style` | `solid` | | +| `ams-alert-border-width` | `4px` |
| +| `ams-alert-gap` | `1rem` |
| +| `ams-alert-padding-block` | `1rem` |
| +| `ams-alert-padding-inline` | `1.5rem` |
| +| `ams-alert-error-border-color` | `ams.color.primary-red` |
| +| `ams-alert-info-border-color` | `ams.color.primary-blue` |
| +| `ams-alert-success-border-color` | `ams.color.dark-green` |
| + +#### 3.5.1 Compact mode + +The following tokens have different values in compact mode: + +| Name | Value | Preview | +| :------------------------- | :-------- | :----------------------------------------------- | +| `ams-alert-gap` | `0.75rem` |
| +| `ams-alert-padding-block` | `0.75rem` |
| +| `ams-alert-padding-inline` | `1rem` |
| + +#### 3.5.2 Dark mode + +The following tokens have different values in dark mode: + +… + +## 4. Further Reading + +References to relevant articles, documentation, or best practices related to the component. + +- [Links to cross-origin destinations are unsafe](https://developer.chrome.com/docs/lighthouse/best-practices/external-anchors-use-rel-noopener/): Avoid `target="_blank"` or use `rel="external noopener"` if necessary. +- [_A comprehensive guide to designing perfect links in UX_, on Prototypr](https://blog.prototypr.io/a-guide-to-designing-perfect-links-in-ux-414558f35730): Best practices for links. +- [_Writing Hyperlinks: Salient, Descriptive, Start with Keyword_ by Norman Nielsen Group](https://www.nngroup.com/articles/writing-links/): How to write good links? An extensive article on links. +- [_Hover, focus, active_, by Wunder](https://wunder.io/wunderpedia/accessibility/accessible-uis/hover-focus-active/): A good explanation of the states that elements like links and buttons have in browsers. +- [MDN: ``: The Anchor element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a): Comprehensive overview of all possibilities of links in HTML. + +## 5. Version History and Changelog + +Document the version history of the component, including release dates and notable changes. +Include a changelog detailing bug fixes, improvements, and new features introduced in each version. + +- **0.7.0** _Lorem ipsum dolor sit amet, consectetur adipisicing elit. Doloremque fuga iusto sequi?_ +- **0.6.1** _Lorem ipsum dolor sit amet, consectetur adipisicing elit. Atque beatae delectus dolor eligendi excepturi laborum libero minima neque tempore tenetur._ +- **0.4.0** _Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aspernatur eos ex labore, maiores quas sequi totam._ + +## 6. Feedback + +An easy way to provide feedback on this page. +Maybe thumbs up and down and a small textarea. +And a link to GitHub to suggest a change through a PR. + +## (How to write) + +We write our documentation in British English and conform to the Schrijfwijzer where possible. + +Short sentences, short paragraphs, lists only when they are actually lists. diff --git a/storybook/src/components/Component/Component.stories.tsx b/storybook/src/components/Component/Component.stories.tsx new file mode 100644 index 0000000000..0d41f02960 --- /dev/null +++ b/storybook/src/components/Component/Component.stories.tsx @@ -0,0 +1,38 @@ +/** + * @license EUPL-1.2+ + * Copyright Gemeente Amsterdam + */ + +import { Component, Paragraph } from '@amsterdam/design-system-react' +import { Meta, StoryObj } from '@storybook/react' + +const meta = { + title: 'Component', + component: Component, + args: { + children: 'Interactive demo showcasing the component in action.', + size: 'small', + }, + argTypes: { + size: { + control: { + type: 'radio', + labels: { small: 'small', undefined: 'medium', large: 'large' }, + }, + options: ['small', undefined, 'large'], + }, + }, + decorators: [ + (Story) => ( + + + + ), + ], +} satisfies Meta + +export default meta + +type Story = StoryObj + +export const Default: Story = {}