@postnord/web-components
Version:
PostNord Web Components
228 lines (227 loc) • 7.97 kB
JavaScript
/*!
* Built with Stencil
* By PostNord.
*/
import { createDocumentation, createComponent } from "../../../globals/documentation/story";
import docs from "./pn-checkbox-docs.json";
import { getFigmaUrl } from "../../../globals/figmaLinks";
const { argTypes, textContent } = createDocumentation(docs);
/**
* The checkbox component comes packaged with a lot of features to make accessibility and styling easy for you.
* You can use the helpertext feature, turn it into a tile with icon support and toggle various states (disabled, readonly, etc...).
*
* While we recommend you to always use the `label` prop, you can discard it and use your own.
* Make sure your label has the `for="{id}"` attribute pointing to the `checkboxid="{id}"`.
*
* In the examples below, we use the [pn-fieldset](./?path=/docs/components-input-fieldset--docs) to give context to the checkboxes.
**/
const meta = {
title: 'Components/Input/Checkbox',
parameters: {
actions: {
handles: ['change'],
},
design: {
type: 'figma',
url: getFigmaUrl(import.meta.url),
},
},
args: {
label: 'Home',
value: '',
name: '',
checked: false,
helpertext: '',
checkboxid: '',
disabled: false,
required: false,
invalid: false,
indeterminate: false,
tile: false,
icon: '',
},
argTypes,
};
meta.argTypes.icon.if = { arg: 'tile', eq: true };
export default meta;
export const PnCheckbox = {
name: 'pn-checkbox',
parameters: {
docs: {
description: {
story: textContent,
},
},
},
render: (args, context) => {
const container = createComponent('pn-fieldset', { legend: 'Where can we deliver your parcel?' });
const checkbox1 = createComponent('pn-checkbox', args);
const checkbox2 = createComponent('pn-checkbox', {
...args,
label: 'Parcel locker',
helpertext: args.helpertext ? 'Deliver the package to the nearest parcel locker.' : null,
value: '2',
checkboxid: context.id + '2',
icon: args.icon ? 'company' : null,
});
const checkbox3 = createComponent('pn-checkbox', {
...args,
label: 'Pickup location',
helpertext: args.helpertext ? 'Send my parcel to a pickup location.' : null,
value: '3',
checkboxid: context.id + '3',
icon: args.icon ? 'small_business' : '',
});
container.appendChild(checkbox1);
container.appendChild(checkbox2);
container.appendChild(checkbox3);
return container;
},
};
/**
* While we strongly recommend you use our built in features (that comes with accesible markup),
* you may sometimes need to only use the checkbox itself.
*
* Just make sure you provide a label element that points to the checkbox ID.
**/
export const PnCheckboxNoLabel = {
name: 'pn-checkbox (no label)',
render: args => {
const checkbox = createComponent('pn-checkbox', args);
return checkbox;
},
args: {
label: '',
},
};
/** You can add a `helpertext` to the checkboxes. */
export const PnCheckboxHelpertext = {
name: 'pn-checkbox (helpertext)',
render: PnCheckbox.render,
args: {
helpertext: 'Deliver the parcel to my home.',
},
};
/**
* You can set the checkbox as `invalid` and apply the error styling.
* The checkbox does not have the option to present its own error message, however, you can assign it on a wrapping pn-fieldset!
*/
export const PnCheckboxError = {
name: 'pn-checkbox (invalid)',
render: PnCheckbox.render,
args: {
invalid: true,
},
};
/** You can disable the checkbox with the `disabled` prop. */
export const PnCheckboxDisabled = {
name: 'pn-checkbox (disabled)',
render: PnCheckbox.render,
args: {
disabled: true,
},
};
/**
* With the `tile` prop, you can turn the checkbox into a checkbox tile.
* Making it a little larger and allows you to select an `icon` for it if you wish.
**/
export const PnCheckboxTile = {
name: 'pn-checkbox (tile)',
render: PnCheckbox.render,
args: {
tile: true,
},
};
/** You can combine the `tile` with all other available props. For example, the `helpertext` and `icon`. */
export const PnCheckboxTileProps = {
name: 'pn-checkbox (tile + any prop)',
render: PnCheckbox.render,
args: {
tile: true,
helpertext: PnCheckboxHelpertext.args.helpertext,
icon: 'home',
},
};
/**
* An example of when to use the `indeterminate` prop.
*
* A common use case is to use it when you have a checkbox that toggles all of the following options when clicked.
* We simply mark it as indeterminate when at least one checkbox has a different checked state compared to its siblings.
*
**/
export const PnCheckboxIndeterminate = {
name: 'pn-checkbox (indeterminate)',
render: args => {
const fieldset = createComponent('pn-fieldset', {
legend: 'User settings',
helpertext: 'Change your preferences.',
});
const checkbox = createComponent('pn-checkbox', args);
const checkboxOne = createComponent('pn-checkbox', {
...args,
label: 'Email notifications',
helpertext: 'Get notified by email when something happens.',
value: 'email',
checked: args.checked,
indeterminate: false,
});
const checkboxTwo = createComponent('pn-checkbox', {
...args,
label: 'Push notifications',
helpertext: 'Get push notifications from the browser.',
value: 'push',
checked: !args.checked,
indeterminate: false,
});
const checkboxThree = createComponent('pn-checkbox', {
...args,
label: 'SMS notifications',
helpertext: 'Get notified by text messages.',
checked: args.checked,
indeterminate: false,
name: 'sms',
});
fieldset.appendChild(checkbox);
fieldset.appendChild(checkboxOne);
fieldset.appendChild(checkboxTwo);
fieldset.appendChild(checkboxThree);
const all = [checkboxOne, checkboxTwo, checkboxThree];
const toggleAll = (checked) => {
all.forEach(item => item.setAttribute('checked', checked));
checkbox.setAttribute('checked', checked);
checkbox.removeAttribute('indeterminate');
};
checkbox.addEventListener('change', ({ target }) => {
const { checked } = target;
toggleAll(checked.toString());
});
fieldset.addEventListener('change', ({ target }) => {
const input = target;
if (input.name === args.name)
return;
input.closest('pn-checkbox').setAttribute('checked', input.checked.toString());
const allChecked = all.every(item => item.checked);
const allUnchecked = all.every(item => !item.checked);
if (allChecked) {
checkbox.setAttribute('checked', 'true');
checkbox.setAttribute('indeterminate', 'false');
return;
}
if (allUnchecked) {
checkbox.setAttribute('checked', 'false');
checkbox.setAttribute('indeterminate', 'false');
return;
}
checkbox.setAttribute('checked', 'false');
checkbox.setAttribute('indeterminate', 'true');
});
return fieldset;
},
args: {
label: 'Get all notifications',
helpertext: 'Get all of our notifications across all channels.',
indeterminate: true,
value: 'all',
},
};
//# sourceMappingURL=pn-checkbox.stories.js.map