Skip to content

Commit

Permalink
Merge pull request #152 from Greater-London-Authority/inputs
Browse files Browse the repository at this point in the history
Modifies the Select compnent to use the selte-select library, and implement consistent wrappers/chrome around select and input elements.
  • Loading branch information
jamesscottbrown authored Nov 15, 2023
2 parents 0e5bc06 + b6f643d commit 5f31ecb
Show file tree
Hide file tree
Showing 17 changed files with 612 additions and 122 deletions.
7 changes: 7 additions & 0 deletions .changeset/stupid-ads-tap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@ldn-viz/ui': major
---

CHANGED - the select component is now based on the `svelte-select` library
ADDED - a new `Tooltip` component allows the display of help tooltips when an icon is hovered over
ADDED - an `InputWrapper` provides consisten chrome (such as help text or error messages) around input elements
7 changes: 6 additions & 1 deletion apps/docs/.storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
<!-- see https://storybook.js.org/docs/react/configure/images-and-assets#referencing-fonts-in-stories -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=EB+Garamond&family=Roboto:wght@100;400;500;700&display=swap"
rel="stylesheet"
/>
33 changes: 31 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"packages/*"
],
"dependencies": {
"@changesets/cli": "^2.26.1"
"@changesets/cli": "^2.26.1",
"svelte-select": "^5.7.0"
},
"overrides": {
"@rgossiaux/svelte-headlessui": {
Expand Down
14 changes: 9 additions & 5 deletions packages/themes/ldn-theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const config = {
'border-color': ldnColors.core.grey[300],

'&:disabled': {
'background-color': ldnColors.core.grey[200]
'background-color': ldnColors.core.grey[100]
}
},
'.form-input, .form-textarea, .form-select, .form-multiselect': {
Expand All @@ -38,14 +38,18 @@ const config = {
'border-color': ldnColors.core.blue[600]
}
},
'.form-input::placeholder, .form-textarea::placeholder': {
color: ldnColors.core.grey[300]
},
'.form-checkbox, .form-radio': {
color: ldnColors.core.blue[600],
'&:focus': {
'--tw-ring-color': ldnColors.core.blue[600]
}
},
'.form-label': {
color: ldnColors.core.grey[700]
color: ldnColors.core.grey[700],
'font-weight': '500'
},
'.form-select': {
'background-image': `url("${svgToDataUri(
Expand All @@ -55,19 +59,19 @@ const config = {
'.dark': {
'.form-input, .form-textarea, .form-select, .form-multiselect, .form-checkbox, .form-radio':
{
'border-color': ldnColors.core.grey[400],
'border-color': ldnColors.core.grey[600],
'background-color': ldnColors.core.grey[600],
color: ldnColors.core.grey[50],
'&:focus': {
'--tw-ring-offset-color': ldnColors.core.grey[800]
},
'&:disabled, &:disabled::placeholder': {
'background-color': ldnColors.core.grey[400],
color: ldnColors.core.grey[600]
color: ldnColors.core.grey[300]
}
},
'.form-input::placeholder, .form-textarea::placeholder': {
color: ldnColors.core.grey[200]
color: ldnColors.core.grey[300]
},
'.form-checkbox, .form-radio': {
color: ldnColors.core.blue[600]
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
"@types/d3-dsv": "^3.0.1",
"d3-dsv": "^3.0.1",
"postcss-cli": "^10.1.0",
"postcss-discard-comments": "^6.0.0"
"postcss-discard-comments": "^6.0.0",
"svelte-floating-ui": "^1.5.3"
},
"overrides": {
"@rgossiaux/svelte-headlessui": {
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/lib/button/Button.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@
on:touchcancel
on:mouseenter
on:mouseleave
role="button"
tabindex="0"
>
<slot />
</svelte:element>
19 changes: 6 additions & 13 deletions packages/ui/src/lib/index.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
// Reexport your entry components here
export { default as Button } from './button/Button.svelte';

export { default as Checkbox } from './checkBox/Checkbox.svelte';
export { default as CheckboxGroup } from './checkBox/CheckboxGroup.svelte';

export { default as DataDownloadButton } from './dataDownloadButton/DataDownloadButton.svelte';
export { default as Header } from './header/Header.svelte';
export { default as HeaderItem } from './header/HeaderItem.svelte';
export { default as HeaderRight } from './header/HeaderRight.svelte';
export { default as HeaderTitle } from './header/HeaderTitle.svelte';
export { default as NavLink } from './header/NavLink.svelte';
export { default as NavLinks } from './header/NavLinks.svelte';

export { default as ImageDownloadButton } from './imageDownloadButton/ImageDownloadButton.svelte';
export { default as LogoByCIU } from './logos/LogoByCIU.svelte';
export { default as LogoCIU } from './logos/LogoCIU.svelte';
export { default as LogoLOTI } from './logos/LogoLOTI.svelte';
export { default as LogoMayor } from './logos/LogoMayor.svelte';

export { default as Modal } from './modal/Modal.svelte';

export { default as Header } from './header/Header.svelte';
export { default as HeaderItem } from './header/HeaderItem.svelte';
export { default as HeaderRight } from './header/HeaderRight.svelte';
export { default as HeaderTitle } from './header/HeaderTitle.svelte';
export { default as NavLink } from './header/NavLink.svelte';
export { default as NavLinks } from './header/NavLinks.svelte';

export { default as PlacardButton } from './placardButton/PlacardButton.svelte';

export { default as RadioButton } from './radioButton/RadioButton.svelte';
export { default as RadioButtonGroup } from './radioButton/RadioButtonGroup.svelte';

export { default as RadioButtonGroupSolid } from './radioButtonSolid/RadioButtonGroupSolid.svelte';
export { default as RadioButtonSolid } from './radioButtonSolid/RadioButtonSolid.svelte';

export { default as Select } from './select/Select.svelte';
export { default as Spinner } from './spinners/Spinner.svelte';
export { default as TabbedSidebar } from './tabbedSidebar/TabbedSidebar.svelte';
export { default as TabbedSidebarTabLabel } from './tabbedSidebar/TabbedSidebarTabLabel.svelte';
export { default as TabbedSidebarTabList } from './tabbedSidebar/TabbedSidebarTabList.svelte';
export { default as TabbedSidebarWrapper } from './tabbedSidebar/TabbedSidebarWrapper.svelte';

export { default as TabLabel } from './tabs/TabLabel.svelte';
export { default as TabList } from './tabs/TabList.svelte';
83 changes: 83 additions & 0 deletions packages/ui/src/lib/input/Input.stories.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<script>
import { Meta, Story } from '@storybook/addon-svelte-csf';
import Input from './Input.svelte';
</script>

<Meta title="Ui/Input" component={Input} />

<Story name="Default">
<div class="w-96">
<Input id="default" />
</div>
</Story>

<Story name="With Label">
<div class="w-96">
<Input label="Label" id="labelled-input" />
</div>
</Story>

<Story name="More Chrome">
<div class="w-96">
<Input
label="Label"
id="labelled-input"
placeholder="Placeholder text"
hint
hintText="Tooltip text"
hintTooltipContent="A brief contextual help message"
description="descriptive text"
optional
/>
</div>
</Story>

<Story name="Description alignment">
<div class="w-96">
<Input
label="Label"
id="labelled-input"
placeholder="Placeholder text"
hint
hintText="Tooltip text"
hintTooltipContent="A brief contextual help message"
description="descriptive text"
descriptionAlignment="right"
optional
/>
</div>
</Story>

<Story name="Error">
<div class="w-96">
<Input
label="Label"
id="labelled-input"
placeholder="Placeholder text"
hint
hintText="Tooltip text"
hintTooltipContent="A brief contextual help message"
description="descriptive text"
optional
error
errorMessage="something has gone wrong here"
/>
</div>
</Story>

<Story name="Disabled">
<div class="w-96">
<Input
label="Label"
id="labelled-input"
placeholder="Placeholder text"
hint
hintText="Tooltip text"
hintTooltipContent="A brief contextual help message"
description="descriptive text"
disabled
optional
/>
</div>
</Story>
25 changes: 25 additions & 0 deletions packages/ui/src/lib/input/Input.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script lang="ts">
import { classNames } from '../utils/classNames';
import InputWrapper from './InputWrapper.svelte';
export let id: string;
export let name = '';
export let placeholder = '';
export let type = 'text';
export let disabled = false;
export let error = false;
if (!name) {
name = id;
}
$: inputClasses = classNames(
error ? 'border-core-red-400 dark:border-core-red-400' : '',
disabled ? 'cursor-not-allowed ' : '',
'form-input'
);
</script>

<InputWrapper {...$$restProps} {id} {disabled} {error}>
<input class={inputClasses} {id} {name} {placeholder} {type} {disabled} />
</InputWrapper>
65 changes: 65 additions & 0 deletions packages/ui/src/lib/input/InputWrapper.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<script lang="ts">
import Tooltip from '../tooltip/Tooltip.svelte';
import { classNames } from '../utils/classNames';
export let label = '';
export let description = '';
export let descriptionAlignment: 'left' | 'right' = 'left';
export let hint = false;
export let hintLabel = 'what is this?';
export let hintTooltipContent = 'A brief contextual help text';
export let error = false;
export let errorMessage = '';
export let disabled = false;
export let optional = false;
// TODO: hint below?
// prefix and suffix slots
export let id: string;
//const id = crypto.randomUUID() ;
let descriptionClass: string;
$: descriptionClass = classNames(
error ? 'text-core-red-400 dark:text-core-red-400' : '',
descriptionAlignment === 'left'
? 'text-core-grey-500 dark:text-core-grey-200'
: 'ml-auto text-core-grey-400 dark:text-core-grey-300',
'text-sm'
);
$: labelClasses = classNames(
error ? 'text-core-red-400 dark:text-core-red-400' : '',
disabled ? 'text-core-grey-300 dark:text-core-grey-400' : '',
'form-label'
);
</script>

<div class="flex flex-col space-y-2">
<div class="flex justify-between">
{#if label}
<label for={id} class={labelClasses}>
{label}{#if optional}&nbsp;(optional){/if}
</label>
{/if}

{#if hint}
<Tooltip {hintLabel}>
{hintTooltipContent}
</Tooltip>
{/if}
</div>

<slot {id} />

{#if description && !errorMessage}
<span class={descriptionClass}>{description}</span>
{:else if errorMessage}
<span class={descriptionClass}>{errorMessage}</span>
{/if}
</div>

5 changes: 2 additions & 3 deletions packages/ui/src/lib/select/Introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ import { Meta } from '@storybook/blocks';

The `Select` component allows users to select an option form a drop-down list of alternatives.

It may [have a label](./?path=/story/ui-select--with-label),
[have an initially value/initially selected item](./?path=/story/ui-select--with-initial-value) or
[be disabled](./?path=/story/ui-select--disabled).
Our select element is a wrapper around ['Svelte Select'](https://github.com/rob-balfre/svelte-select)
Check the documentation for advanced usage and a full list of props, events, slots etc.
Loading

0 comments on commit 5f31ecb

Please sign in to comment.