diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..10842a650 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": ["Bash(yarn test:*)", "Bash(find:*)"], + "deny": [], + "ask": [] + } +} diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index f71f74de1..000000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "permissions": { - "allow": ["Bash(fi:*)", "Bash(done)", "Bash(yarn test:unit:*)"], - "deny": [], - "ask": [] - } -} diff --git a/.gitignore b/.gitignore index 35ae3bd9e..5b7d54f1c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ !.env.example node_modules +# Claude Code local settings +.claude/*.local.json + # Yarn 4 without Zero-installs .pnp.* .yarn/* diff --git a/docs/code-review-checklist.md b/docs/code-review-checklist.md index 2f42e3963..08d9cc59d 100644 --- a/docs/code-review-checklist.md +++ b/docs/code-review-checklist.md @@ -10,7 +10,7 @@ When performing code review, double check all of the items below: - [ ] All new components, functions and other entities are documented - [ ] The repo documentation markdown files are updated if the changes touch upon those. - [ ] If the change adds functions available to the user, tracking events are enabled with new ones defined if needed. -- [ ] Any new Svelte components that have been created, follow the [Svelte component guidelines](contributing.md#svelte-components). +- [ ] Any new Svelte components that have been created follow the [Svelte component guidelines](contributing.md#svelte-components). - [ ] Errors are handled properly and logged in the code. - [ ] Troubleshoot any failing checks in the PR. - [ ] Check that parts of the application that share dependencies with the PR but are not included in it are not unduly affected. diff --git a/docs/contributing.md b/docs/contributing.md index 8b11f6531..03ac6d607 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -379,7 +379,14 @@ let className: $$Props['class'] = $$props['class']; Follow Svelte's [guidelines for component documentation](https://svelte.dev/docs/faq#how-do-i-document-my-components). For an example, see [`IconBase`](/frontend/src/lib/components/icon/base/IconBase.svelte) component and its associated [type definition](/frontend/src/lib/components/icon/base/IconBase.type.ts). -Place the Svelte docstring at the top of the file, before the `
diff --git a/frontend/src/lib/components/controller/InfoMessages.type.ts b/frontend/src/lib/components/controller/InfoMessages.type.ts new file mode 100644 index 000000000..3af684d9b --- /dev/null +++ b/frontend/src/lib/components/controller/InfoMessages.type.ts @@ -0,0 +1,9 @@ +import type { SvelteHTMLElements } from 'svelte/elements'; +import type { JobMessage } from '$lib/server/admin/jobs/jobStore.type'; + +export type InfoMessagesProps = SvelteHTMLElements['div'] & { + /** + * Array of informational messages to display. @default [] + */ + messages?: Array; +}; diff --git a/frontend/src/lib/components/controller/ProgressBar.svelte b/frontend/src/lib/components/controller/ProgressBar.svelte index e685282b7..b4cf7a718 100644 --- a/frontend/src/lib/components/controller/ProgressBar.svelte +++ b/frontend/src/lib/components/controller/ProgressBar.svelte @@ -1,15 +1,45 @@ -
diff --git a/frontend/src/lib/components/controller/WarningMessages.type.ts b/frontend/src/lib/components/controller/WarningMessages.type.ts new file mode 100644 index 000000000..d2b7da11c --- /dev/null +++ b/frontend/src/lib/components/controller/WarningMessages.type.ts @@ -0,0 +1,13 @@ +import type { SvelteHTMLElements } from 'svelte/elements'; +import type { JobMessage } from '$lib/server/admin/jobs/jobStore.type'; + +export type WarningMessagesProps = SvelteHTMLElements['div'] & { + /** + * Array of warning messages to display. @default [] + */ + warnings?: Array; + /** + * Array of error messages to display. @default [] + */ + errors?: Array; +}; diff --git a/frontend/src/lib/components/controller/index.ts b/frontend/src/lib/components/controller/index.ts index e91df14d9..c9041285e 100644 --- a/frontend/src/lib/components/controller/index.ts +++ b/frontend/src/lib/components/controller/index.ts @@ -1,3 +1,6 @@ export { default as InfoMessages } from './InfoMessages.svelte'; +export * from './InfoMessages.type'; export { default as ProgressBar } from './ProgressBar.svelte'; +export * from './ProgressBar.type'; export { default as WarningMessages } from './WarningMessages.svelte'; +export * from './WarningMessages.type'; diff --git a/frontend/src/lib/components/electionTag/ElectionTag.svelte b/frontend/src/lib/components/electionTag/ElectionTag.svelte index 55d138e81..b9ad41f80 100644 --- a/frontend/src/lib/components/electionTag/ElectionTag.svelte +++ b/frontend/src/lib/components/electionTag/ElectionTag.svelte @@ -7,8 +7,8 @@ Used when the application has multiple elections and question may apply to only ### Properties - `election`: The `Election` object. -- `variant`: Whether to use an abbreviation or the full name. @default `'short'` -- `onShadedBg`: Set to `true` if using the component on a dark (`base-300`) background. @default false +- `variant`: Whether to use an abbreviation or the full name. Default: `'short'` +- `onShadedBg`: Set to `true` if using the component on a dark (`base-300`) background. Default: `false` - Any valid attributes of a `` element. ### Usage diff --git a/frontend/src/lib/components/entityFilters/EntityFilters.svelte b/frontend/src/lib/components/entityFilters/EntityFilters.svelte index 41fdce52a..572f69e52 100644 --- a/frontend/src/lib/components/entityFilters/EntityFilters.svelte +++ b/frontend/src/lib/components/entityFilters/EntityFilters.svelte @@ -4,9 +4,9 @@ Show filters for entities. This component and the individual filter components o ### Properties -- `filters`: The filter objects to render. +- `filterGroup`: The filters applied to the contents. - `targets`: The target entitiess of the filter objects. Note that these will only be used to get value options, not for actual filtering. -- Any valid attributes of a `
` element +- Any valid attributes of a `
` element. ### Usage diff --git a/frontend/src/lib/components/entityFilters/text/TextEntityFilter.svelte b/frontend/src/lib/components/entityFilters/text/TextEntityFilter.svelte index 3e1d194fc..712dd7450 100644 --- a/frontend/src/lib/components/entityFilters/text/TextEntityFilter.svelte +++ b/frontend/src/lib/components/entityFilters/text/TextEntityFilter.svelte @@ -4,9 +4,10 @@ Render a text filter for entities. ### Properties -- `filter`: The text filter object to render. -- `placeholder`: The placeholder text. @default `$t('entityFilters.text.placeholder')` -- Any valid attributes of a `
` element +- `filter`: The text filter object. +- `placeholder`: The placeholder text. Default: `$t('components.entityFilters.text.placeholder')` +- `variant`: The styling variant for the text field. Default: `'default'` +- Any valid attributes of a `
` element. ### Usage diff --git a/frontend/src/lib/components/entityTag/EntityTag.svelte b/frontend/src/lib/components/entityTag/EntityTag.svelte index b3e713bb7..ce59e4ce0 100644 --- a/frontend/src/lib/components/entityTag/EntityTag.svelte +++ b/frontend/src/lib/components/entityTag/EntityTag.svelte @@ -5,8 +5,8 @@ Used to display an `Entity` as small tag including an icon. ### Properties - `entity`: A possibly wrapped entity, e.g. candidate or a party. -- `variant`: Whether to use an abbreviation or the full name. @default `'default'` -- `hideParent`: Whether to hide the possible parent nomination. @default false +- `variant`: Whether to use an abbreviation or the full name. Default: `'default'` +- `hideParent`: Whether to hide the possible parent nomination. Default: `false` - Any valid attributes of a `
` element. ### Usage diff --git a/frontend/src/lib/components/errorMessage/ErrorMessage.svelte b/frontend/src/lib/components/errorMessage/ErrorMessage.svelte index e01af11cd..0a0ccc966 100644 --- a/frontend/src/lib/components/errorMessage/ErrorMessage.svelte +++ b/frontend/src/lib/components/errorMessage/ErrorMessage.svelte @@ -4,9 +4,9 @@ Used to display an error message. Also logs the error to the console. ### Properties -- `inline`: Whether to show an inline version of the message. By default the message tries to center itself in the available area and displays a large emoji. @default `false` -- `message`: The message to display. Default `$t('error.default')` -- `logMessage`: The message to log in the console in development mode. @default value of `message` +- `inline`: Whether to show an inline version of the message. By default the message tries to center itself in the available area and displays a large emoji. Default: `false` +- `message`: The message to display. Default: `$t('error.default')` +- `logMessage`: The message to log in the console in development mode. Default: value of `message` - Any valid attributes of a `
` element. ### Usage diff --git a/frontend/src/lib/components/expander/Expander.svelte b/frontend/src/lib/components/expander/Expander.svelte index 2d03b9438..a116b1497 100644 --- a/frontend/src/lib/components/expander/Expander.svelte +++ b/frontend/src/lib/components/expander/Expander.svelte @@ -13,15 +13,14 @@ A component for expanders that contain a title and some content. Use the ### Properties -- `title`: Title used for the expander. This is also used as the aria-label for - the checkbox on which the expander operates on. -- `variant`: The type for the expander. -- `iconColor`: The color for the icon. Default color is primary. -- `iconPos`: The position for the icon. Default is text, which means the icon will - be where the text ends. -- `titleClass`: Custom class string to add to the `
` containing the title. -- `contentClass`: Custom class string to add to the `
` containing the main content. +- `title`: Title is seen as the text in the expander's visible part, and it is mandatory. Title will also be used as a 'aria-label' for a checkbow on which the expander operates on. +- `iconColor`: The color of the next-icon that is used in the expander. Default: `'primary'` +- `iconPos`: The position of the next-icon that is used in the expander. Default: `'text'` +- `titleClass`: Variable with which to configure the expanders title if no variants are in use. +- `contentClass`: Variable with which to configure the expanders content if no variants are in use. - `defaultExpanded`: Variable used to define if the expander is expanded or not by default. +- `variant`: Variable used to define a variant for the expander. +- Any valid attributes of a `
` element. You should not try to use a variant and customize at the same time. diff --git a/frontend/src/lib/components/headingGroup/HeadingGroup.svelte b/frontend/src/lib/components/headingGroup/HeadingGroup.svelte index 6d417dd21..47b2a329e 100644 --- a/frontend/src/lib/components/headingGroup/HeadingGroup.svelte +++ b/frontend/src/lib/components/headingGroup/HeadingGroup.svelte @@ -5,8 +5,8 @@ and the main title. ### Properties -- `aria-roledescription`: The Aria role description of the `
` element representing the pre-title. @default $t('components.headingGroup.roleDescription') -- `role`: The Aria role of the `
` element. @default 'group' +- `aria-roledescription`: The Aria role description of the `
` element. Default: `$t('aria.headingGroup')` +- `role`: The Aria role of the `
` element. Default: `'group'` - Any valid attributes of a `
` element. ### Slots diff --git a/frontend/src/lib/components/headingGroup/PreHeading.svelte b/frontend/src/lib/components/headingGroup/PreHeading.svelte index ad66f50ba..6787d4b1e 100644 --- a/frontend/src/lib/components/headingGroup/PreHeading.svelte +++ b/frontend/src/lib/components/headingGroup/PreHeading.svelte @@ -4,7 +4,7 @@ Used for a pre-title, or kicker, above the main title of a page within a `Headin ### Properties -- `aria-roledescription`: The Aria role description of the `

` element representing the pre-title. @default $t('components.preHeading.roleDescription') +- `aria-roledescription`: The Aria role description of the `

` element representing the pre-title. Default: `$t('aria.preHeading')` - Any valid attributes of a `

` element. ### Slots diff --git a/frontend/src/lib/components/heroEmoji/HeroEmoji.svelte b/frontend/src/lib/components/heroEmoji/HeroEmoji.svelte index d22e9486e..1727a70b4 100644 --- a/frontend/src/lib/components/heroEmoji/HeroEmoji.svelte +++ b/frontend/src/lib/components/heroEmoji/HeroEmoji.svelte @@ -12,10 +12,7 @@ using the `class` attribute, e.g. `class="text-[10rem]"`. ### Properties -- `emoji`: The emoji to use. Note that all non-emoji characters will be removed. If `undefined` the component will not be rendered at all. @default `undefined` -- `aria-hidden`: @default `true` -- `role`: Aria role @default `img` -- `class`: Additional class string to append to the element's default classes. +- `emoji`: The emoji to use. Note that all non-emoji characters will be removed. If `undefined` the component will not be rendered at all. Default: `undefined` - Any valid attributes of a `

` element. ### Usage diff --git a/frontend/src/lib/components/icon/Icon.svelte b/frontend/src/lib/components/icon/Icon.svelte index 283cc596e..f3b8e1bbc 100644 --- a/frontend/src/lib/components/icon/Icon.svelte +++ b/frontend/src/lib/components/icon/Icon.svelte @@ -8,15 +8,12 @@ any valid attributes of the `` element. ### Properties -- `name`: the name of the icon to use -- `size`: The size of the icon as one of the predefined sizes 'sm', 'md' or 'lg'. For arbitrary values, you can supply a `class` property, such as `h-[3.15rem] w-[3.15rem]`. @default 'md' -- `color`: The color of the icon as one of the predefined colours. For arbitrary values, use the `customColor` and `customColorDark` properties. @default 'current' +- `name`: The name of the icon to use. +- `size`: The size of the icon as one of the predefined sizes 'sm', 'md' or 'lg'. For arbitrary values, you can supply a `class` property, such as `h-[3.15rem] w-[3.15rem]`. Default: `'md'` +- `color`: The color of the icon as one of the predefined colours. For arbitrary values, use the `customColor` and `customColorDark` properties. Default: `'current'` - `customColor`: A custom color string to use for the icon, e.g. in case of parties, which will override the `color` property. Make sure to define both `customColor` and `customColorDark` together. - `customColorDark`: A custom color string to use for the icon in dark mode, which will override the `color` property. -- `aria-hidden`: @default `true` -- `role`: Aria role @default `img` -- `class`: Additional class string to append to the element's default classes. -- Any valid attributes of a `` element +- Any valid attributes of a `` element. ### Usage diff --git a/frontend/src/lib/components/infoAnswer/InfoAnswer.svelte b/frontend/src/lib/components/infoAnswer/InfoAnswer.svelte index 4d4f9b472..e6d333ce7 100644 --- a/frontend/src/lib/components/infoAnswer/InfoAnswer.svelte +++ b/frontend/src/lib/components/infoAnswer/InfoAnswer.svelte @@ -6,7 +6,7 @@ Used to display a possibly wrapped entity's answer to an info question. Dependin - `answer`: The possibly missing answer to the question. - `question`: The info question object. -- `format`: How to format the answer. @default `default` +- `format`: How to format the answer. Default: `'default'` - `default`: use the same format as in ``. - `tag`: format the answers as a pill or tag. Nb. links are always rendered as tags. - Any valid common attributes of an HTML element. diff --git a/frontend/src/lib/components/infoBadge/InfoBadge.svelte b/frontend/src/lib/components/infoBadge/InfoBadge.svelte index a0d03016c..ab99d8d55 100644 --- a/frontend/src/lib/components/infoBadge/InfoBadge.svelte +++ b/frontend/src/lib/components/infoBadge/InfoBadge.svelte @@ -1,16 +1,18 @@
diff --git a/frontend/src/lib/components/input/PreviewAllInputs.type.ts b/frontend/src/lib/components/input/PreviewAllInputs.type.ts new file mode 100644 index 000000000..57b5e77cc --- /dev/null +++ b/frontend/src/lib/components/input/PreviewAllInputs.type.ts @@ -0,0 +1,12 @@ +import type { SvelteHTMLElements } from 'svelte/elements'; + +export type PreviewAllInputsProps = SvelteHTMLElements['div'] & { + /** + * Optional info text to display with inputs. + */ + info?: string; + /** + * Whether inputs are locked. @default false + */ + locked?: boolean; +}; diff --git a/frontend/src/lib/components/input/index.ts b/frontend/src/lib/components/input/index.ts index f24890611..a57399a6f 100644 --- a/frontend/src/lib/components/input/index.ts +++ b/frontend/src/lib/components/input/index.ts @@ -2,6 +2,8 @@ export { default as Input } from './Input.svelte'; export * from './Input.type'; export { default as InputGroup } from './InputGroup.svelte'; export * from './InputGroup.type'; +export { default as PreviewAllInputs } from './PreviewAllInputs.svelte'; +export * from './PreviewAllInputs.type'; export { default as QuestionInput } from './QuestionInput.svelte'; export * from './QuestionInput.type'; export * from './shared'; diff --git a/frontend/src/lib/components/loading/Loading.svelte b/frontend/src/lib/components/loading/Loading.svelte index 797018e8b..4139ea182 100644 --- a/frontend/src/lib/components/loading/Loading.svelte +++ b/frontend/src/lib/components/loading/Loading.svelte @@ -4,10 +4,10 @@ Used to display a loading spinner with an optionally visible text label. ### Properties -- `inline`: Whether to show an inline version of the spinner. By default the spinner tries to center itself in the available area. @default `false` -- `label`: he label text. @default `$t('common.loading')` -- `showLabel`: Whether to show the text label. The label will always be shown to screen readers. @default `false` -- `size`: The size of the loading spinner. @default `'lg'` +- `inline`: Whether to show an inline version of the spinner. By default the spinner tries to center itself in the available area. Default: `false` +- `label`: The label text. Default: `$t('common.loading')` +- `showLabel`: Whether to show the text label. The label will always be shown to screen readers. Default: `false` +- `size`: The size of the loading spinner. Default: `'lg'` - Any valid attributes of a `
` element. ### Usage diff --git a/frontend/src/lib/components/matchScore/MatchScore.svelte b/frontend/src/lib/components/matchScore/MatchScore.svelte index ec10ca6d0..125984298 100644 --- a/frontend/src/lib/components/matchScore/MatchScore.svelte +++ b/frontend/src/lib/components/matchScore/MatchScore.svelte @@ -5,7 +5,8 @@ Display an entity's match score. ### Properties - `score`: The match score as a `string` or a `number`. Note that `$t('components.matchScore.label')` will be used display the score. -- `label`: The label to display under the score. @default `$t('components.matchScore.label')` +- `label`: The label to display under the score. Default: `$t('components.matchScore.label')` +- `showLabel`: Whether to show the label. Default: `true` - Any valid attributes of a `
` element ### Usage diff --git a/frontend/src/lib/components/openVAALogo/OpenVAALogo.svelte b/frontend/src/lib/components/openVAALogo/OpenVAALogo.svelte index 4f30aa7ba..ae420a21b 100644 --- a/frontend/src/lib/components/openVAALogo/OpenVAALogo.svelte +++ b/frontend/src/lib/components/openVAALogo/OpenVAALogo.svelte @@ -8,15 +8,10 @@ attributes of one. ### Properties -- `title`: The `` of the SVG logo. Functions much the same way as the `alt`` - attribute of an `<img>`. -- `color`: The color of the logo as one of the predefined colours. - For arbitrary values, you can supply a `class` property, such as - `fill-[#123456]`. @default `'neutral'` - - `size`: The size of the logo as one of the predefined sizes 'sm', 'md' or 'lg'. - For arbitrary values, you can supply a `class` attribute, such as - `class="h-[3.5rem]"`. @default `'md'` - - Any valid attributes of a `<svg>` element +- `title`: The `<title>` of the SVG logo. Functions much the same way as the `alt` attribute of an `<img>`. Default: `'OpenVAA'` +- `size`: The size of the logo as one of the predefined sizes 'sm', 'md' or 'lg'. For arbitrary values, you can supply a `class` property, such as `h-[3.15rem] w-[3.15rem]`. Default: `'md'` +- `color`: The color of the logo as one of the predefined colours. For arbitrary values, you can supply a `class` property, such as `fill-[#123456]`. Default: `'neutral'` +- Any valid attributes of a `<svg>` element. ### Usage diff --git a/frontend/src/lib/components/successMessage/SuccessMessage.svelte b/frontend/src/lib/components/successMessage/SuccessMessage.svelte index d787cffa1..ff849744f 100644 --- a/frontend/src/lib/components/successMessage/SuccessMessage.svelte +++ b/frontend/src/lib/components/successMessage/SuccessMessage.svelte @@ -4,8 +4,8 @@ Used to display a message when an action succeeds. ### Properties -- `inline`: Whether to show an inline version of the message. By default the message tries to center itself in the available area and displays a large emoji. @default `false` -- `message`: The error message to display. Default `$t('common.success')` +- `inline`: Whether to show an inline version of the message. By default the message tries to center itself in the available area and displays a large emoji. Default: `false` +- `message`: The message to display. Default: `$t('common.success')` - Any valid attributes of a `<div>` element. ### Usage diff --git a/frontend/src/lib/dynamic-components/appLogo/AppLogo.svelte b/frontend/src/lib/dynamic-components/appLogo/AppLogo.svelte index 64002c7e2..6be371a3f 100644 --- a/frontend/src/lib/dynamic-components/appLogo/AppLogo.svelte +++ b/frontend/src/lib/dynamic-components/appLogo/AppLogo.svelte @@ -10,11 +10,10 @@ Logo files for use on a light and a dark background can be defined. If the latte ### Properties -- `alt`: The `alt` text for the logo image. -- `inverse`: If `true`, the light and dark versions of the logo will be reversed. Set to `true` if using the logo on a dark background. @default `false` -- `size`: The size of the logo as one of the predefined sizes 'sm', 'md' or 'lg'. For arbitrary values, you can supply a `class` attribute, such as `class="h-[3.5rem]"`. @default `'md'` -- `class`: Additional class string to append to the element's default classes. -- Any valid attributes of the `<div>` element wrapping the light and dark `<img>` elements +- `alt`: The `alt` text for the logo image. If missing, the publisher name or 'OpenVAA' will be used, depending on the logo shown. +- `inverse`: If `true`, the light and dark versions of the logo will be reversed. Set to `true` if using the logo on a dark background. Default: `false` +- `size`: The size of the logo as one of the predefined sizes 'sm', 'md' or 'lg'. For arbitrary values, you can supply a `class` attribute, such as `class="h-[3.5rem]"`. Default: `'md'` +- Any valid attributes of a `<div>` element ### Usage diff --git a/frontend/src/lib/dynamic-components/dataConsent/DataConsent.svelte b/frontend/src/lib/dynamic-components/dataConsent/DataConsent.svelte index 06aca1b97..cc995a86d 100644 --- a/frontend/src/lib/dynamic-components/dataConsent/DataConsent.svelte +++ b/frontend/src/lib/dynamic-components/dataConsent/DataConsent.svelte @@ -8,10 +8,10 @@ Accesses `AppContext` to set and read `userPreferences`. ### Properties -- `description`: Whether and how to show the data consent description. @default `modal` - - `none`: Don’t show the description. - - `inline`: Show the consent description above the buttons. - - `modal`: Show a button that opens the description in a modal. +- `description`: Whether and how to show the data consent description. Default: `'modal'` + - `'none'`: Don't show the description. + - `'inline'`: Show the consent description above the buttons. + - `'modal'`: Show a button that opens the description in a modal. - Any valid attributes of a `<div>` element. ### Events diff --git a/frontend/src/lib/dynamic-components/entityCard/EntityCard.svelte b/frontend/src/lib/dynamic-components/entityCard/EntityCard.svelte index bfb2604ad..02a9f2b02 100644 --- a/frontend/src/lib/dynamic-components/entityCard/EntityCard.svelte +++ b/frontend/src/lib/dynamic-components/entityCard/EntityCard.svelte @@ -12,14 +12,14 @@ This is a dynamic component, because it accesses the `dataRoot` and other proper ### Properties -- `action`: Custom action to take when the card is clicked, defaults to a link to the entity’s `ResultEntity` route. If the card has subentites, the action will only be triggered by clicking the content above them. -- `entity`: A possibly ranked nakedEntity, e.g. candidate or a party. -- `variant`: The variant-dependend layout variant. Usually set automatically. - - `'list'`: In a list of entities. The default. +- `action`: Custom action to take when the card is clicked, defaults to a link to the entity's `ResultEntity` route. If the card has subentites, the action will only be triggered by clicking the content above them. +- `entity`: A possibly ranked entity, e.g. candidate or a party. +- `variant`: The context-dependend layout variant. Usually set automatically. Default: `'list'` + - `'list'`: In a list of entities. - `'details'`: As part of the header of `EntityDetails`. - - `'subcard'`; In a list of nested nakedEntity cards, e.g., the candidates for a party. -- `maxSubcards`: The maximum number of sub-entities to show. If there are more a button will be shown for displaying the remaining ones. @default `3` -- `showElection`: Whether to show the possible nomination’s election and constituency. @default `false` + - `'subcard'`: In a list of nested entity cards, e.g., the candidates for a party. +- `maxSubcards`: The maximum number of sub-entities to show. If there are more a button will be shown for displaying the remaining ones. Default: `3` +- `showElection`: Whether to show the possible nomination's election and constituency. Default: `false` - Any valid attributes of an `<article>` element. ### Tracking events diff --git a/frontend/src/lib/dynamic-components/entityCard/EntityCardAction.svelte b/frontend/src/lib/dynamic-components/entityCard/EntityCardAction.svelte index 44f00a43f..62fed30f0 100644 --- a/frontend/src/lib/dynamic-components/entityCard/EntityCardAction.svelte +++ b/frontend/src/lib/dynamic-components/entityCard/EntityCardAction.svelte @@ -6,7 +6,7 @@ TODO[Svelte 5]: Maybe convert into `$snippet`. ### Properties - `action`: The action to take when the part or card is clicked. -- `shadeOnHover`: Whether to shade the element on hover. Use when applying to subcards or their parent card's header. @default `false` +- `shadeOnHover`: Whether to shade the element on hover. Use when applying to subcards or their parent card's header. Default: `false` - Any valid attributes common to HTML elements. Note that these will only be applied if `<EntityCardAction>` is rendered. ### Slots diff --git a/frontend/src/lib/dynamic-components/entityDetails/EntityChildren.svelte b/frontend/src/lib/dynamic-components/entityDetails/EntityChildren.svelte index f9d35a0b0..6a22e33f2 100644 --- a/frontend/src/lib/dynamic-components/entityDetails/EntityChildren.svelte +++ b/frontend/src/lib/dynamic-components/entityDetails/EntityChildren.svelte @@ -4,9 +4,10 @@ Used to show an entity's children in an `EntityDetails` component. ### Properties -- `entities`: An array of possibly ranked entities, e.g. a party’s candidates. -- `entityType`: The type of the entities being displayed. Used to pick correct translations +- `entities`: An array of possibly ranked entities, e.g. a party's candidates. +- `entityType`: The type of the entities being displayed. Used to pick correct translations. - `action`: An optional callback for building the card actions for the child possible entities. If nullish, the default action filled in by `EntityCard` will be used. If `false`, no actions will be added. +- Any valid attributes of a `<div>` element ### Usage @@ -19,12 +20,14 @@ Used to show an entity's children in an `EntityDetails` component. import { getComponentContext } from '$lib/contexts/component'; import { EntityList } from '$lib/dynamic-components/entityList'; import { EntityListControls } from '../entityList'; - import type { EntityType } from '@openvaa/data'; - import type { CardAction, EntityCardProps } from '../entityCard'; + import type { EntityCardProps } from '../entityCard'; + import type { EntityChildrenProps } from './EntityChildren.type'; - export let entities: Array<MaybeWrappedEntityVariant>; - export let entityType: EntityType; - export let action: ((entity: MaybeWrappedEntityVariant) => CardAction) | false | null | undefined = undefined; + type $$Props = EntityChildrenProps; + + export let entities: $$Props['entities']; + export let entityType: $$Props['entityType']; + export let action: $$Props['action'] = undefined; //////////////////////////////////////////////////////////////////// // Get contexts diff --git a/frontend/src/lib/dynamic-components/entityDetails/EntityChildren.type.ts b/frontend/src/lib/dynamic-components/entityDetails/EntityChildren.type.ts new file mode 100644 index 000000000..b48b291f4 --- /dev/null +++ b/frontend/src/lib/dynamic-components/entityDetails/EntityChildren.type.ts @@ -0,0 +1,18 @@ +import type { EntityType } from '@openvaa/data'; +import type { SvelteHTMLElements } from 'svelte/elements'; +import type { CardAction } from '../entityCard'; + +export type EntityChildrenProps = SvelteHTMLElements['div'] & { + /** + * An array of possibly ranked entities, e.g. a party's candidates. + */ + entities: Array<MaybeWrappedEntityVariant>; + /** + * The type of the entities being displayed. Used to pick correct translations. + */ + entityType: EntityType; + /** + * An optional callback for building the card actions for the child possible entities. If nullish, the default action filled in by `EntityCard` will be used. If `false`, no actions will be added. + */ + action?: ((entity: MaybeWrappedEntityVariant) => CardAction) | false | null; +}; diff --git a/frontend/src/lib/dynamic-components/entityDetails/EntityInfo.svelte b/frontend/src/lib/dynamic-components/entityDetails/EntityInfo.svelte index 3889983ed..2824a7d75 100644 --- a/frontend/src/lib/dynamic-components/entityDetails/EntityInfo.svelte +++ b/frontend/src/lib/dynamic-components/entityDetails/EntityInfo.svelte @@ -9,7 +9,8 @@ This is a dynamic component, because it accesses `appSettings` and `dataRoot` fr ### Properties - `entity`: A possibly ranked entity, e.g. candidate or a party. -- `questions`: An array of `info` questions +- `questions`: An array of `info` questions. +- Any valid attributes of a `<div>` element ### Settings @@ -28,7 +29,6 @@ This is a dynamic component, because it accesses `appSettings` and `dataRoot` fr import { type AnyEntityVariant, type AnyNominationVariant, - type AnyQuestionVariant, ENTITY_TYPE, type EntityType, isObjectType, @@ -42,10 +42,12 @@ This is a dynamic component, because it accesses `appSettings` and `dataRoot` fr import { unwrapEntity } from '$lib/utils/entities'; import { sanitizeHtml } from '$lib/utils/sanitize'; import InfoItem from './InfoItem.svelte'; - import type { EntityDetailsProps } from './EntityDetails.type'; + import type { EntityInfoProps } from './EntityInfo.type'; - export let entity: EntityDetailsProps['entity']; - export let questions: Array<AnyQuestionVariant>; + type $$Props = EntityInfoProps; + + export let entity: $$Props['entity']; + export let questions: $$Props['questions']; //////////////////////////////////////////////////////////////////// // Get contexts diff --git a/frontend/src/lib/dynamic-components/entityDetails/EntityInfo.type.ts b/frontend/src/lib/dynamic-components/entityDetails/EntityInfo.type.ts new file mode 100644 index 000000000..0527f27ca --- /dev/null +++ b/frontend/src/lib/dynamic-components/entityDetails/EntityInfo.type.ts @@ -0,0 +1,14 @@ +import type { AnyQuestionVariant } from '@openvaa/data'; +import type { SvelteHTMLElements } from 'svelte/elements'; +import type { EntityDetailsProps } from './EntityDetails.type'; + +export type EntityInfoProps = SvelteHTMLElements['div'] & { + /** + * A possibly ranked entity, e.g. candidate or a party. + */ + entity: EntityDetailsProps['entity']; + /** + * An array of `info` questions. + */ + questions: Array<AnyQuestionVariant>; +}; diff --git a/frontend/src/lib/dynamic-components/entityDetails/EntityOpinions.svelte b/frontend/src/lib/dynamic-components/entityDetails/EntityOpinions.svelte index a029d3be7..9c80eb680 100644 --- a/frontend/src/lib/dynamic-components/entityDetails/EntityOpinions.svelte +++ b/frontend/src/lib/dynamic-components/entityDetails/EntityOpinions.svelte @@ -6,7 +6,8 @@ Used to show an entity's answers to `opinion` questions and possibly those of th - `entity`: A possibly ranked entity, e.g. candidate or a party. - `questions`: An array of `opinion` questions. -- `answers`: An optional `AnswerStore` with the Voter’s answers to the questions. +- `answers`: An optional `AnswerStore` with the Voter's answers to the questions. +- Any valid attributes of a `<div>` element ### Usage @@ -21,13 +22,14 @@ Used to show an entity's answers to `opinion` questions and possibly those of th import { OpinionQuestionInput, QuestionOpenAnswer } from '$lib/components/questions'; import { getAppContext } from '$lib/contexts/app'; import { unwrapEntity } from '$lib/utils/entities'; - import type { AnyEntityVariant, AnyQuestionVariant } from '@openvaa/data'; - import type { AnswerStore } from '$lib/contexts/voter'; - import type { EntityDetailsProps } from './EntityDetails.type'; + import type { AnyEntityVariant } from '@openvaa/data'; + import type { EntityOpinionsProps } from './EntityOpinions.type'; - export let entity: EntityDetailsProps['entity']; - export let questions: Array<AnyQuestionVariant>; - export let answers: AnswerStore | undefined = undefined; + type $$Props = EntityOpinionsProps; + + export let entity: $$Props['entity']; + export let questions: $$Props['questions']; + export let answers: $$Props['answers'] = undefined; //////////////////////////////////////////////////////////////////// // Get contexts diff --git a/frontend/src/lib/dynamic-components/entityDetails/EntityOpinions.type.ts b/frontend/src/lib/dynamic-components/entityDetails/EntityOpinions.type.ts new file mode 100644 index 000000000..c96327f1d --- /dev/null +++ b/frontend/src/lib/dynamic-components/entityDetails/EntityOpinions.type.ts @@ -0,0 +1,19 @@ +import type { AnyQuestionVariant } from '@openvaa/data'; +import type { SvelteHTMLElements } from 'svelte/elements'; +import type { AnswerStore } from '$lib/contexts/voter'; +import type { EntityDetailsProps } from './EntityDetails.type'; + +export type EntityOpinionsProps = SvelteHTMLElements['div'] & { + /** + * A possibly ranked entity, e.g. candidate or a party. + */ + entity: EntityDetailsProps['entity']; + /** + * An array of `opinion` questions. + */ + questions: Array<AnyQuestionVariant>; + /** + * An optional `AnswerStore` with the Voter's answers to the questions. + */ + answers?: AnswerStore; +}; diff --git a/frontend/src/lib/dynamic-components/entityDetails/InfoItem.svelte b/frontend/src/lib/dynamic-components/entityDetails/InfoItem.svelte index 38b40ede7..d4797ab50 100644 --- a/frontend/src/lib/dynamic-components/entityDetails/InfoItem.svelte +++ b/frontend/src/lib/dynamic-components/entityDetails/InfoItem.svelte @@ -4,8 +4,9 @@ Used to show a label-content pair in a Candidate's basic information. ### Properties -- `label`: the label of the information -- `vertical`: layout mode for the item +- `label`: The label of the information. +- `vertical`: Layout mode for the item. Default: `false` +- Any valid attributes of a `<div>` element ### Slots @@ -21,10 +22,12 @@ Used to show a label-content pair in a Candidate's basic information. --> <script lang="ts"> - /** The info label */ - export let label: string; - /** The info layout mode */ - export let vertical = false; + import type { InfoItemProps } from './InfoItem.type'; + + type $$Props = InfoItemProps; + + export let label: $$Props['label']; + export let vertical: $$Props['vertical'] = false; </script> <div class="grid justify-start gap-md {vertical ? 'vertical-grid' : 'horizontal-grid'}"> diff --git a/frontend/src/lib/dynamic-components/entityDetails/InfoItem.type.ts b/frontend/src/lib/dynamic-components/entityDetails/InfoItem.type.ts new file mode 100644 index 000000000..e3248efd0 --- /dev/null +++ b/frontend/src/lib/dynamic-components/entityDetails/InfoItem.type.ts @@ -0,0 +1,12 @@ +import type { SvelteHTMLElements } from 'svelte/elements'; + +export type InfoItemProps = SvelteHTMLElements['div'] & { + /** + * The label of the information. + */ + label: string; + /** + * Layout mode for the item. @default false + */ + vertical?: boolean; +}; diff --git a/frontend/src/lib/dynamic-components/entityDetails/index.ts b/frontend/src/lib/dynamic-components/entityDetails/index.ts index 92236e8f8..54e046dc1 100644 --- a/frontend/src/lib/dynamic-components/entityDetails/index.ts +++ b/frontend/src/lib/dynamic-components/entityDetails/index.ts @@ -1,7 +1,12 @@ export { default as EntityChildren } from './EntityChildren.svelte'; +export * from './EntityChildren.type'; export { default as EntityDetails } from './EntityDetails.svelte'; export * from './EntityDetails.type'; export { default as EntityDetailsDrawer } from './EntityDetailsDrawer.svelte'; export * from './EntityDetailsDrawer.type'; export { default as EntityInfo } from './EntityInfo.svelte'; +export * from './EntityInfo.type'; export { default as EntityOpinions } from './EntityOpinions.svelte'; +export * from './EntityOpinions.type'; +export { default as InfoItem } from './InfoItem.svelte'; +export * from './InfoItem.type'; diff --git a/frontend/src/lib/dynamic-components/entityList/EntityListControls.svelte b/frontend/src/lib/dynamic-components/entityList/EntityListControls.svelte index a45da8189..3f09f4d2d 100644 --- a/frontend/src/lib/dynamic-components/entityList/EntityListControls.svelte +++ b/frontend/src/lib/dynamic-components/entityList/EntityListControls.svelte @@ -7,14 +7,11 @@ TODO: Consider moving the tracking events away from the component and just addin ### Properties - `entities`: A list of possibly ranked entities, e.g. candidates or a parties. -- `filterGroup`: The filters applied to the entities -- `searchProperty`: The property used for the search tool. Default 'name' +- `filterGroup`: The filters applied to the contents. +- `searchProperty`: The property used for the search tool. Default: `'name'` +- `onUpdate`: Callback for when the filters are applied. - Any valid attributes of a `<div>` element. -### Callbacks - -- `onUpdate`: Callback for when the filters are applied. - ### Tracking events - `filters_reset` diff --git a/frontend/src/lib/dynamic-components/feedback/Feedback.svelte b/frontend/src/lib/dynamic-components/feedback/Feedback.svelte index 3eeaad309..96c23a4f0 100644 --- a/frontend/src/lib/dynamic-components/feedback/Feedback.svelte +++ b/frontend/src/lib/dynamic-components/feedback/Feedback.svelte @@ -8,14 +8,16 @@ Accesses the `AppContext` and the `FeedbackWriter` api. ### Properties +- `showActions`: Whether to show the standard action buttons below the feedback form. Default: `true` +- `variant`: The layout variant of the feedback form. Default: `'default'` - Any valid attributes of a `<form>` element. -### Bindable properties and functions +### Bindable properties -- `status`: The status of the feedback form. @default `'default'` -- `canSubmit`: Bind to this to know whether the feedback can be submitted, i.e. the user has entered something. @default `false` -- `reset()`: Reset the form so that if the user opens it again, they can fill new feedback. You should call this when closing any modal containing the feedback. -- `submit()`: Submit the feedback. +- `canSubmit`: Bind to this to know whether the feedback can be submitted, i.e. the user has entered something. Default: `false` +- `status`: Bind to this to access the status of the feedback form. Default: `'default'` +- `submit`: Submit the feedback or close the modal if it's already been submitted. +- `reset`: Reset the form so that if the user opens it again, they can fill new feedback. You should call this when closing any modal containing the feedback. ### Events diff --git a/frontend/src/lib/dynamic-components/logoutButton/LogoutButton.svelte b/frontend/src/lib/dynamic-components/logoutButton/LogoutButton.svelte index 23f60d4a7..c8c274ebf 100644 --- a/frontend/src/lib/dynamic-components/logoutButton/LogoutButton.svelte +++ b/frontend/src/lib/dynamic-components/logoutButton/LogoutButton.svelte @@ -6,7 +6,13 @@ Allows user to log out. Accesses `AuthContext` and `AppContext`. +### Properties + +- `redirectTo`: The route to redirect to after logging out. Default: `'Home'` +- Any valid properties of a `<Button>` component. + ### Usage + ```tsx <LogoutButton /> ``` diff --git a/frontend/src/lib/dynamic-components/navigation/NavGroup.svelte b/frontend/src/lib/dynamic-components/navigation/NavGroup.svelte index b4c0b27c8..d859ad8bd 100644 --- a/frontend/src/lib/dynamic-components/navigation/NavGroup.svelte +++ b/frontend/src/lib/dynamic-components/navigation/NavGroup.svelte @@ -2,16 +2,14 @@ @component Use to group `NavItem` components. Displays a faint line above the group. -### Slots +### Properties -- default: The contents of the navigation group. Should be mostly -`<NavItem>` components. +- `title`: Optional title for the navigation group. +- Any valid attributes of a `<ul>` element. -### Properties +### Slots -- `role`: Aria role @default `list` -- `class`: Additional class string to append to the element's default classes. -- Any valid attributes of a `<section>` element. +- default: The contents of the navigation group. Should be mostly `<NavItem>` components. ### Usage diff --git a/frontend/src/lib/dynamic-components/navigation/NavItem.svelte b/frontend/src/lib/dynamic-components/navigation/NavItem.svelte index a15125411..af8739c14 100644 --- a/frontend/src/lib/dynamic-components/navigation/NavItem.svelte +++ b/frontend/src/lib/dynamic-components/navigation/NavItem.svelte @@ -10,12 +10,10 @@ Accesses `LayoutContext`. ### Properties -- `href`: The URL to navigate to. If this is not supplied be sure to provide an `on:click` event handler or other way of making the item interactive. -- `icon`: An optional `IconName` of the icon to use. @default `undefined` -- `text`: A required text to display. -- `autoCloseNav`: Whether the menu available from the page context should be closed when the item is clicked. @default `true` +- `icon`: The optional name of the icon to use with the navigation item. See the `Icon` component for more details. +- `text`: The text to display in the navigation item. - `disabled`: Whether the button is disabled. This can also be used with items rendered as `<a>` elements. -- `class`: Additional class string to append to the element's default classes. +- `autoCloseNav`: Whether the menu available from the page context should be closed when the item is clicked. Default: `true` - Any valid attributes of either an `<a>` or `<button>` element depending whether `href` was defined or not, respectively. ### Usage diff --git a/frontend/src/lib/dynamic-components/navigation/Navigation.svelte b/frontend/src/lib/dynamic-components/navigation/Navigation.svelte index cc49d6c74..74f16a6b6 100644 --- a/frontend/src/lib/dynamic-components/navigation/Navigation.svelte +++ b/frontend/src/lib/dynamic-components/navigation/Navigation.svelte @@ -2,16 +2,15 @@ @component Create navigation menus for the application in a predefined style. -### Slots - -- default: The content of the navigation menu. It should mainly consist - of `<NavGroup>` components containing `<NavItem>` components. - ### Properties -- `hidden`: Set to `true` to whenever the navigation is hidden. @default false +- `hidden`: Set to `true` to whenever the navigation is hidden. Default: `false` - Any valid attributes of a `<nav>` element. +### Slots + +- default: The content of the navigation menu. It should mainly consist of `<NavGroup>` components containing `<NavItem>` components. + ### Events - `keyboardFocusOut`: Emitted when the component loses a keyboard user's diff --git a/frontend/src/lib/dynamic-components/navigation/admin/AdminNav.svelte b/frontend/src/lib/dynamic-components/navigation/admin/AdminNav.svelte index dcd72908d..f51986600 100644 --- a/frontend/src/lib/dynamic-components/navigation/admin/AdminNav.svelte +++ b/frontend/src/lib/dynamic-components/navigation/admin/AdminNav.svelte @@ -25,6 +25,10 @@ A template part that outputs the navigation menu for the Admin App for use in `L import { getLayoutContext } from '$lib/contexts/layout'; import { NavGroup, Navigation, NavItem } from '$lib/dynamic-components/navigation'; import { LanguageSelection } from '../languages'; + import type { AdminNavProps } from './AdminNav.type'; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type $$Props = AdminNavProps; const { navigation } = getLayoutContext(onDestroy); const { authToken, t, getRoute } = getAdminContext(); diff --git a/frontend/src/lib/dynamic-components/navigation/admin/AdminNav.type.ts b/frontend/src/lib/dynamic-components/navigation/admin/AdminNav.type.ts new file mode 100644 index 000000000..a51f691d5 --- /dev/null +++ b/frontend/src/lib/dynamic-components/navigation/admin/AdminNav.type.ts @@ -0,0 +1,3 @@ +import type { NavigationProps } from '../Navigation.type'; + +export type AdminNavProps = NavigationProps; diff --git a/frontend/src/lib/dynamic-components/navigation/admin/index.ts b/frontend/src/lib/dynamic-components/navigation/admin/index.ts index fbafe1b5e..01b70f44e 100644 --- a/frontend/src/lib/dynamic-components/navigation/admin/index.ts +++ b/frontend/src/lib/dynamic-components/navigation/admin/index.ts @@ -1 +1,2 @@ export { default as AdminNav } from './AdminNav.svelte'; +export * from './AdminNav.type'; diff --git a/frontend/src/lib/dynamic-components/navigation/candidate/CandidateNav.svelte b/frontend/src/lib/dynamic-components/navigation/candidate/CandidateNav.svelte index bf6ce6e48..965045f03 100644 --- a/frontend/src/lib/dynamic-components/navigation/candidate/CandidateNav.svelte +++ b/frontend/src/lib/dynamic-components/navigation/candidate/CandidateNav.svelte @@ -1,11 +1,15 @@ <!-- @component -A template part that outputs the navigation menu for the Candidate App for use in use in `Layout`. +A template part that outputs the navigation menu for the Candidate App for use in `Layout`. ### Dynamic component - Accesses the `CandidateContext`. +### Properties + +- Any valid properties of a `Navigation` component + ### Usage ```tsx @@ -22,6 +26,10 @@ A template part that outputs the navigation menu for the Candidate App for use i import { getLayoutContext } from '$lib/contexts/layout'; import { NavGroup, Navigation, NavItem } from '$lib/dynamic-components/navigation'; import { LanguageSelection } from '../languages'; + import type { CandidateNavProps } from './CandidateNav.type'; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type $$Props = CandidateNavProps; const { navigation } = getLayoutContext(onDestroy); const { diff --git a/frontend/src/lib/dynamic-components/navigation/candidate/CandidateNav.type.ts b/frontend/src/lib/dynamic-components/navigation/candidate/CandidateNav.type.ts new file mode 100644 index 000000000..540f9db9a --- /dev/null +++ b/frontend/src/lib/dynamic-components/navigation/candidate/CandidateNav.type.ts @@ -0,0 +1,3 @@ +import type { NavigationProps } from '../Navigation.type'; + +export type CandidateNavProps = NavigationProps; diff --git a/frontend/src/lib/dynamic-components/navigation/candidate/index.ts b/frontend/src/lib/dynamic-components/navigation/candidate/index.ts index 17cace842..6a623911a 100644 --- a/frontend/src/lib/dynamic-components/navigation/candidate/index.ts +++ b/frontend/src/lib/dynamic-components/navigation/candidate/index.ts @@ -1 +1,2 @@ export { default as CandidateNav } from './CandidateNav.svelte'; +export * from './CandidateNav.type'; diff --git a/frontend/src/lib/dynamic-components/navigation/voter/VoterNav.svelte b/frontend/src/lib/dynamic-components/navigation/voter/VoterNav.svelte index 6cdb23b66..c5dc05ed3 100644 --- a/frontend/src/lib/dynamic-components/navigation/voter/VoterNav.svelte +++ b/frontend/src/lib/dynamic-components/navigation/voter/VoterNav.svelte @@ -31,6 +31,10 @@ A template part that outputs the navigation menu for the Voter App for use in `L import { getVoterContext } from '$lib/contexts/voter'; import { NavGroup, Navigation, NavItem } from '$lib/dynamic-components/navigation'; import { LanguageSelection } from '../languages'; + import type { VoterNavProps } from './VoterNav.type'; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + type $$Props = VoterNavProps; const { navigation } = getLayoutContext(onDestroy); diff --git a/frontend/src/lib/dynamic-components/navigation/voter/VoterNav.type.ts b/frontend/src/lib/dynamic-components/navigation/voter/VoterNav.type.ts new file mode 100644 index 000000000..96e6ad512 --- /dev/null +++ b/frontend/src/lib/dynamic-components/navigation/voter/VoterNav.type.ts @@ -0,0 +1,3 @@ +import type { NavigationProps } from '../Navigation.type'; + +export type VoterNavProps = NavigationProps; diff --git a/frontend/src/lib/dynamic-components/navigation/voter/index.ts b/frontend/src/lib/dynamic-components/navigation/voter/index.ts index b1457f6fc..0aa55f2fd 100644 --- a/frontend/src/lib/dynamic-components/navigation/voter/index.ts +++ b/frontend/src/lib/dynamic-components/navigation/voter/index.ts @@ -1 +1,2 @@ export { default as VoterNav } from './VoterNav.svelte'; +export * from './VoterNav.type';