From a5a7739d75de642ea6841b61ca4b719be91856b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marianne=20R=C3=B8svik?= Date: Thu, 21 Sep 2023 07:37:58 +0200 Subject: [PATCH 01/40] feat(ErrorMessage): Add Large size token (#839) Co-authored-by: Michael Marszalek --- design-tokens/Base/Semantic.json | 14 ++++++++++++ packages/tokens/brand/altinn/tokens.cjs.js | 1 + packages/tokens/brand/altinn/tokens.css | 1 + packages/tokens/brand/altinn/tokens.d.ts | 1 + packages/tokens/brand/altinn/tokens.esm.js | 1 + packages/tokens/brand/brreg/tokens.cjs.js | 1 + packages/tokens/brand/brreg/tokens.css | 1 + packages/tokens/brand/brreg/tokens.d.ts | 1 + packages/tokens/brand/brreg/tokens.esm.js | 1 + packages/tokens/brand/digdir/tokens.cjs.js | 1 + packages/tokens/brand/digdir/tokens.css | 1 + packages/tokens/brand/digdir/tokens.d.ts | 1 + packages/tokens/brand/digdir/tokens.esm.js | 1 + packages/tokens/brand/tilsynet/tokens.cjs.js | 1 + packages/tokens/brand/tilsynet/tokens.css | 1 + packages/tokens/brand/tilsynet/tokens.d.ts | 1 + packages/tokens/brand/tilsynet/tokens.esm.js | 1 + storefront/tokens/altinn.ts | 23 ++++++++++++++++++++ storefront/tokens/brreg.ts | 23 ++++++++++++++++++++ storefront/tokens/digdir.ts | 23 ++++++++++++++++++++ storefront/tokens/tilsynet.ts | 23 ++++++++++++++++++++ 21 files changed, 122 insertions(+) diff --git a/design-tokens/Base/Semantic.json b/design-tokens/Base/Semantic.json index d4980785bd..a9dda4f529 100644 --- a/design-tokens/Base/Semantic.json +++ b/design-tokens/Base/Semantic.json @@ -856,6 +856,20 @@ } }, "error_message": { + "large": { + "value": { + "fontFamily": "{fontFamilies.inter}", + "fontWeight": "{fontWeights.regular}", + "lineHeight": "{lineHeights.300}", + "fontSize": "{font-size.f1}", + "letterSpacing": "{letterSpacing.1}", + "paragraphSpacing": "{paragraphSpacing.0}", + "paragraphIndent": "{paragraphIndent.0}", + "textCase": "{textCase.none}", + "textDecoration": "{textDecoration.none}" + }, + "type": "typography" + }, "medium": { "value": { "fontFamily": "{fontFamilies.inter}", diff --git a/packages/tokens/brand/altinn/tokens.cjs.js b/packages/tokens/brand/altinn/tokens.cjs.js index 051b5801f5..67a8ab6ded 100644 --- a/packages/tokens/brand/altinn/tokens.cjs.js +++ b/packages/tokens/brand/altinn/tokens.cjs.js @@ -170,6 +170,7 @@ module.exports = { "typography_label_medium": "500 1.125rem/1.3 'Inter'", "typography_label_small": "500 0.9375rem/1.3 'Inter'", "typography_label_xsmall": "500 0.8125rem/1.3 'Inter'", + "typography_error_message_large": "400 1.3125rem/1.3 'Inter'", "typography_error_message_medium": "400 1.125rem/1.3 'Inter'", "typography_error_message_small": "400 0.9375rem/1.3 'Inter'", "typography_error_message_xsmall": "400 0.8125rem/1.3 'Inter'", diff --git a/packages/tokens/brand/altinn/tokens.css b/packages/tokens/brand/altinn/tokens.css index 6f8700209c..d7a412d127 100644 --- a/packages/tokens/brand/altinn/tokens.css +++ b/packages/tokens/brand/altinn/tokens.css @@ -174,6 +174,7 @@ --fds-typography-label-medium: 500 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'; --fds-typography-label-small: 500 clamp(0.91rem, calc(0.10vw + 0.89rem), 0.97rem)/1.3 'Inter'; --fds-typography-label-xsmall: 500 clamp(0.81rem, calc(0.05vw + 0.80rem), 0.84rem)/1.3 'Inter'; + --fds-typography-error_message-large: 400 clamp(1.09rem, calc(0.34vw + 1.03rem), 1.31rem)/1.3 'Inter'; --fds-typography-error_message-medium: 400 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'; --fds-typography-error_message-small: 400 clamp(0.91rem, calc(0.10vw + 0.89rem), 0.97rem)/1.3 'Inter'; --fds-typography-error_message-xsmall: 400 clamp(0.81rem, calc(0.05vw + 0.80rem), 0.84rem)/1.3 'Inter'; diff --git a/packages/tokens/brand/altinn/tokens.d.ts b/packages/tokens/brand/altinn/tokens.d.ts index 1bea6c8114..32e23f2b15 100644 --- a/packages/tokens/brand/altinn/tokens.d.ts +++ b/packages/tokens/brand/altinn/tokens.d.ts @@ -169,6 +169,7 @@ export const typography_label_large : string; export const typography_label_medium : string; export const typography_label_small : string; export const typography_label_xsmall : string; +export const typography_error_message_large : string; export const typography_error_message_medium : string; export const typography_error_message_small : string; export const typography_error_message_xsmall : string; diff --git a/packages/tokens/brand/altinn/tokens.esm.js b/packages/tokens/brand/altinn/tokens.esm.js index 740d43317a..d4cf5bc391 100644 --- a/packages/tokens/brand/altinn/tokens.esm.js +++ b/packages/tokens/brand/altinn/tokens.esm.js @@ -169,6 +169,7 @@ export const typography_label_large = "500 1.3125rem/1.3 'Inter'"; export const typography_label_medium = "500 1.125rem/1.3 'Inter'"; export const typography_label_small = "500 0.9375rem/1.3 'Inter'"; export const typography_label_xsmall = "500 0.8125rem/1.3 'Inter'"; +export const typography_error_message_large = "400 1.3125rem/1.3 'Inter'"; export const typography_error_message_medium = "400 1.125rem/1.3 'Inter'"; export const typography_error_message_small = "400 0.9375rem/1.3 'Inter'"; export const typography_error_message_xsmall = "400 0.8125rem/1.3 'Inter'"; diff --git a/packages/tokens/brand/brreg/tokens.cjs.js b/packages/tokens/brand/brreg/tokens.cjs.js index d9730098fc..c8cb419396 100644 --- a/packages/tokens/brand/brreg/tokens.cjs.js +++ b/packages/tokens/brand/brreg/tokens.cjs.js @@ -170,6 +170,7 @@ module.exports = { "typography_label_medium": "500 1.125rem/1.3 'Inter'", "typography_label_small": "500 0.9375rem/1.3 'Inter'", "typography_label_xsmall": "500 0.8125rem/1.3 'Inter'", + "typography_error_message_large": "400 1.3125rem/1.3 'Inter'", "typography_error_message_medium": "400 1.125rem/1.3 'Inter'", "typography_error_message_small": "400 0.9375rem/1.3 'Inter'", "typography_error_message_xsmall": "400 0.8125rem/1.3 'Inter'", diff --git a/packages/tokens/brand/brreg/tokens.css b/packages/tokens/brand/brreg/tokens.css index 124ed7da86..4240511b50 100644 --- a/packages/tokens/brand/brreg/tokens.css +++ b/packages/tokens/brand/brreg/tokens.css @@ -174,6 +174,7 @@ --fds-typography-label-medium: 500 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'; --fds-typography-label-small: 500 clamp(0.91rem, calc(0.10vw + 0.89rem), 0.97rem)/1.3 'Inter'; --fds-typography-label-xsmall: 500 clamp(0.81rem, calc(0.05vw + 0.80rem), 0.84rem)/1.3 'Inter'; + --fds-typography-error_message-large: 400 clamp(1.09rem, calc(0.34vw + 1.03rem), 1.31rem)/1.3 'Inter'; --fds-typography-error_message-medium: 400 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'; --fds-typography-error_message-small: 400 clamp(0.91rem, calc(0.10vw + 0.89rem), 0.97rem)/1.3 'Inter'; --fds-typography-error_message-xsmall: 400 clamp(0.81rem, calc(0.05vw + 0.80rem), 0.84rem)/1.3 'Inter'; diff --git a/packages/tokens/brand/brreg/tokens.d.ts b/packages/tokens/brand/brreg/tokens.d.ts index 8cd8e31fee..24c8b6bb0a 100644 --- a/packages/tokens/brand/brreg/tokens.d.ts +++ b/packages/tokens/brand/brreg/tokens.d.ts @@ -169,6 +169,7 @@ export const typography_label_large : string; export const typography_label_medium : string; export const typography_label_small : string; export const typography_label_xsmall : string; +export const typography_error_message_large : string; export const typography_error_message_medium : string; export const typography_error_message_small : string; export const typography_error_message_xsmall : string; diff --git a/packages/tokens/brand/brreg/tokens.esm.js b/packages/tokens/brand/brreg/tokens.esm.js index 9e7ac8ee57..5da4ce17f0 100644 --- a/packages/tokens/brand/brreg/tokens.esm.js +++ b/packages/tokens/brand/brreg/tokens.esm.js @@ -169,6 +169,7 @@ export const typography_label_large = "500 1.3125rem/1.3 'Inter'"; export const typography_label_medium = "500 1.125rem/1.3 'Inter'"; export const typography_label_small = "500 0.9375rem/1.3 'Inter'"; export const typography_label_xsmall = "500 0.8125rem/1.3 'Inter'"; +export const typography_error_message_large = "400 1.3125rem/1.3 'Inter'"; export const typography_error_message_medium = "400 1.125rem/1.3 'Inter'"; export const typography_error_message_small = "400 0.9375rem/1.3 'Inter'"; export const typography_error_message_xsmall = "400 0.8125rem/1.3 'Inter'"; diff --git a/packages/tokens/brand/digdir/tokens.cjs.js b/packages/tokens/brand/digdir/tokens.cjs.js index b537bd9e66..24ab7f8b60 100644 --- a/packages/tokens/brand/digdir/tokens.cjs.js +++ b/packages/tokens/brand/digdir/tokens.cjs.js @@ -170,6 +170,7 @@ module.exports = { "typography_label_medium": "500 1.125rem/1.3 'Inter'", "typography_label_small": "500 0.9375rem/1.3 'Inter'", "typography_label_xsmall": "500 0.8125rem/1.3 'Inter'", + "typography_error_message_large": "400 1.3125rem/1.3 'Inter'", "typography_error_message_medium": "400 1.125rem/1.3 'Inter'", "typography_error_message_small": "400 0.9375rem/1.3 'Inter'", "typography_error_message_xsmall": "400 0.8125rem/1.3 'Inter'", diff --git a/packages/tokens/brand/digdir/tokens.css b/packages/tokens/brand/digdir/tokens.css index 682c2c4991..befd6a0d87 100644 --- a/packages/tokens/brand/digdir/tokens.css +++ b/packages/tokens/brand/digdir/tokens.css @@ -174,6 +174,7 @@ --fds-typography-label-medium: 500 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'; --fds-typography-label-small: 500 clamp(0.91rem, calc(0.10vw + 0.89rem), 0.97rem)/1.3 'Inter'; --fds-typography-label-xsmall: 500 clamp(0.81rem, calc(0.05vw + 0.80rem), 0.84rem)/1.3 'Inter'; + --fds-typography-error_message-large: 400 clamp(1.09rem, calc(0.34vw + 1.03rem), 1.31rem)/1.3 'Inter'; --fds-typography-error_message-medium: 400 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'; --fds-typography-error_message-small: 400 clamp(0.91rem, calc(0.10vw + 0.89rem), 0.97rem)/1.3 'Inter'; --fds-typography-error_message-xsmall: 400 clamp(0.81rem, calc(0.05vw + 0.80rem), 0.84rem)/1.3 'Inter'; diff --git a/packages/tokens/brand/digdir/tokens.d.ts b/packages/tokens/brand/digdir/tokens.d.ts index 1bea6c8114..32e23f2b15 100644 --- a/packages/tokens/brand/digdir/tokens.d.ts +++ b/packages/tokens/brand/digdir/tokens.d.ts @@ -169,6 +169,7 @@ export const typography_label_large : string; export const typography_label_medium : string; export const typography_label_small : string; export const typography_label_xsmall : string; +export const typography_error_message_large : string; export const typography_error_message_medium : string; export const typography_error_message_small : string; export const typography_error_message_xsmall : string; diff --git a/packages/tokens/brand/digdir/tokens.esm.js b/packages/tokens/brand/digdir/tokens.esm.js index 759f1ea0c7..cbfed8b067 100644 --- a/packages/tokens/brand/digdir/tokens.esm.js +++ b/packages/tokens/brand/digdir/tokens.esm.js @@ -169,6 +169,7 @@ export const typography_label_large = "500 1.3125rem/1.3 'Inter'"; export const typography_label_medium = "500 1.125rem/1.3 'Inter'"; export const typography_label_small = "500 0.9375rem/1.3 'Inter'"; export const typography_label_xsmall = "500 0.8125rem/1.3 'Inter'"; +export const typography_error_message_large = "400 1.3125rem/1.3 'Inter'"; export const typography_error_message_medium = "400 1.125rem/1.3 'Inter'"; export const typography_error_message_small = "400 0.9375rem/1.3 'Inter'"; export const typography_error_message_xsmall = "400 0.8125rem/1.3 'Inter'"; diff --git a/packages/tokens/brand/tilsynet/tokens.cjs.js b/packages/tokens/brand/tilsynet/tokens.cjs.js index 37a0d8c8c3..4951971611 100644 --- a/packages/tokens/brand/tilsynet/tokens.cjs.js +++ b/packages/tokens/brand/tilsynet/tokens.cjs.js @@ -170,6 +170,7 @@ module.exports = { "typography_label_medium": "500 1.125rem/1.3 'Inter'", "typography_label_small": "500 0.9375rem/1.3 'Inter'", "typography_label_xsmall": "500 0.8125rem/1.3 'Inter'", + "typography_error_message_large": "400 1.3125rem/1.3 'Inter'", "typography_error_message_medium": "400 1.125rem/1.3 'Inter'", "typography_error_message_small": "400 0.9375rem/1.3 'Inter'", "typography_error_message_xsmall": "400 0.8125rem/1.3 'Inter'", diff --git a/packages/tokens/brand/tilsynet/tokens.css b/packages/tokens/brand/tilsynet/tokens.css index 8613065b1c..0b4aaa11c2 100644 --- a/packages/tokens/brand/tilsynet/tokens.css +++ b/packages/tokens/brand/tilsynet/tokens.css @@ -174,6 +174,7 @@ --fds-typography-label-medium: 500 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'; --fds-typography-label-small: 500 clamp(0.91rem, calc(0.10vw + 0.89rem), 0.97rem)/1.3 'Inter'; --fds-typography-label-xsmall: 500 clamp(0.81rem, calc(0.05vw + 0.80rem), 0.84rem)/1.3 'Inter'; + --fds-typography-error_message-large: 400 clamp(1.09rem, calc(0.34vw + 1.03rem), 1.31rem)/1.3 'Inter'; --fds-typography-error_message-medium: 400 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'; --fds-typography-error_message-small: 400 clamp(0.91rem, calc(0.10vw + 0.89rem), 0.97rem)/1.3 'Inter'; --fds-typography-error_message-xsmall: 400 clamp(0.81rem, calc(0.05vw + 0.80rem), 0.84rem)/1.3 'Inter'; diff --git a/packages/tokens/brand/tilsynet/tokens.d.ts b/packages/tokens/brand/tilsynet/tokens.d.ts index 1bea6c8114..32e23f2b15 100644 --- a/packages/tokens/brand/tilsynet/tokens.d.ts +++ b/packages/tokens/brand/tilsynet/tokens.d.ts @@ -169,6 +169,7 @@ export const typography_label_large : string; export const typography_label_medium : string; export const typography_label_small : string; export const typography_label_xsmall : string; +export const typography_error_message_large : string; export const typography_error_message_medium : string; export const typography_error_message_small : string; export const typography_error_message_xsmall : string; diff --git a/packages/tokens/brand/tilsynet/tokens.esm.js b/packages/tokens/brand/tilsynet/tokens.esm.js index 1d93cf04d2..e64a5b525f 100644 --- a/packages/tokens/brand/tilsynet/tokens.esm.js +++ b/packages/tokens/brand/tilsynet/tokens.esm.js @@ -169,6 +169,7 @@ export const typography_label_large = "500 1.3125rem/1.3 'Inter'"; export const typography_label_medium = "500 1.125rem/1.3 'Inter'"; export const typography_label_small = "500 0.9375rem/1.3 'Inter'"; export const typography_label_xsmall = "500 0.8125rem/1.3 'Inter'"; +export const typography_error_message_large = "400 1.3125rem/1.3 'Inter'"; export const typography_error_message_medium = "400 1.125rem/1.3 'Inter'"; export const typography_error_message_small = "400 0.9375rem/1.3 'Inter'"; export const typography_error_message_xsmall = "400 0.8125rem/1.3 'Inter'"; diff --git a/storefront/tokens/altinn.ts b/storefront/tokens/altinn.ts index c95d2d85d1..ae222b56bc 100644 --- a/storefront/tokens/altinn.ts +++ b/storefront/tokens/altinn.ts @@ -2784,6 +2784,29 @@ export const typography = [ attributes: {}, path: ['typography', 'label', 'xsmall'], }, + { + value: "400 clamp(1.09rem, calc(0.34vw + 1.03rem), 1.31rem)/1.3 'Inter'", + type: 'typography', + filePath: '../../design-tokens/Base/Semantic.json', + isSource: false, + original: { + value: { + fontFamily: '{fontFamilies.inter}', + fontWeight: '{fontWeights.regular}', + lineHeight: '{lineHeights.300}', + fontSize: '{font-size.f1}', + letterSpacing: '{letterSpacing.1}', + paragraphSpacing: '{paragraphSpacing.0}', + paragraphIndent: '{paragraphIndent.0}', + textCase: '{textCase.none}', + textDecoration: '{textDecoration.none}', + }, + type: 'typography', + }, + name: '--fds-typography-error_message-large', + attributes: {}, + path: ['typography', 'error_message', 'large'], + }, { value: "400 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'", type: 'typography', diff --git a/storefront/tokens/brreg.ts b/storefront/tokens/brreg.ts index 97372bc0b3..ee12519cf7 100644 --- a/storefront/tokens/brreg.ts +++ b/storefront/tokens/brreg.ts @@ -2802,6 +2802,29 @@ export const typography = [ attributes: {}, path: ['typography', 'label', 'xsmall'], }, + { + value: "400 clamp(1.09rem, calc(0.34vw + 1.03rem), 1.31rem)/1.3 'Inter'", + type: 'typography', + filePath: '../../design-tokens/Base/Semantic.json', + isSource: false, + original: { + value: { + fontFamily: '{fontFamilies.inter}', + fontWeight: '{fontWeights.regular}', + lineHeight: '{lineHeights.300}', + fontSize: '{font-size.f1}', + letterSpacing: '{letterSpacing.1}', + paragraphSpacing: '{paragraphSpacing.0}', + paragraphIndent: '{paragraphIndent.0}', + textCase: '{textCase.none}', + textDecoration: '{textDecoration.none}', + }, + type: 'typography', + }, + name: '--fds-typography-error_message-large', + attributes: {}, + path: ['typography', 'error_message', 'large'], + }, { value: "400 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'", type: 'typography', diff --git a/storefront/tokens/digdir.ts b/storefront/tokens/digdir.ts index 7643ff3fbe..42101b4e7f 100644 --- a/storefront/tokens/digdir.ts +++ b/storefront/tokens/digdir.ts @@ -2778,6 +2778,29 @@ export const typography = [ attributes: {}, path: ['typography', 'label', 'xsmall'], }, + { + value: "400 clamp(1.09rem, calc(0.34vw + 1.03rem), 1.31rem)/1.3 'Inter'", + type: 'typography', + filePath: '../../design-tokens/Base/Semantic.json', + isSource: false, + original: { + value: { + fontFamily: '{fontFamilies.inter}', + fontWeight: '{fontWeights.regular}', + lineHeight: '{lineHeights.300}', + fontSize: '{font-size.f1}', + letterSpacing: '{letterSpacing.1}', + paragraphSpacing: '{paragraphSpacing.0}', + paragraphIndent: '{paragraphIndent.0}', + textCase: '{textCase.none}', + textDecoration: '{textDecoration.none}', + }, + type: 'typography', + }, + name: '--fds-typography-error_message-large', + attributes: {}, + path: ['typography', 'error_message', 'large'], + }, { value: "400 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'", type: 'typography', diff --git a/storefront/tokens/tilsynet.ts b/storefront/tokens/tilsynet.ts index 6a3839df0b..d636e43cf3 100644 --- a/storefront/tokens/tilsynet.ts +++ b/storefront/tokens/tilsynet.ts @@ -2724,6 +2724,29 @@ export const typography = [ attributes: {}, path: ['typography', 'label', 'xsmall'], }, + { + value: "400 clamp(1.09rem, calc(0.34vw + 1.03rem), 1.31rem)/1.3 'Inter'", + type: 'typography', + filePath: '../../design-tokens/Base/Semantic.json', + isSource: false, + original: { + value: { + fontFamily: '{fontFamilies.inter}', + fontWeight: '{fontWeights.regular}', + lineHeight: '{lineHeights.300}', + fontSize: '{font-size.f1}', + letterSpacing: '{letterSpacing.1}', + paragraphSpacing: '{paragraphSpacing.0}', + paragraphIndent: '{paragraphIndent.0}', + textCase: '{textCase.none}', + textDecoration: '{textDecoration.none}', + }, + type: 'typography', + }, + name: '--fds-typography-error_message-large', + attributes: {}, + path: ['typography', 'error_message', 'large'], + }, { value: "400 clamp(1.00rem, calc(0.19vw + 0.96rem), 1.13rem)/1.3 'Inter'", type: 'typography', From 9742abf1d002967fdfdb6b3caa8f33bb11a85019 Mon Sep 17 00:00:00 2001 From: Michael Marszalek Date: Thu, 21 Sep 2023 08:01:07 +0200 Subject: [PATCH 02/40] =?UTF-8?q?feat(ErrorMessage):=20=E2=9C=A8=20Add=20`?= =?UTF-8?q?large`=20size=20(#840)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Typography/ErrorMessage/ErrorMessage.module.css | 7 +++++++ .../components/Typography/ErrorMessage/ErrorMessage.tsx | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/react/src/components/Typography/ErrorMessage/ErrorMessage.module.css b/packages/react/src/components/Typography/ErrorMessage/ErrorMessage.module.css index 831d41eb4e..1830300e98 100644 --- a/packages/react/src/components/Typography/ErrorMessage/ErrorMessage.module.css +++ b/packages/react/src/components/Typography/ErrorMessage/ErrorMessage.module.css @@ -13,6 +13,13 @@ margin-bottom: var(--fdsc-bottom-spacing); } +.errorMessage.large { + --fdsc-bottom-spacing: var(--fds-spacing-5); + + font: var(--fds-typography-error_message-large); + font-family: var(--fdsc-typography-font-family); +} + .errorMessage.medium { --fdsc-bottom-spacing: var(--fds-spacing-5); diff --git a/packages/react/src/components/Typography/ErrorMessage/ErrorMessage.tsx b/packages/react/src/components/Typography/ErrorMessage/ErrorMessage.tsx index ed0d9fbefb..bf62c32f91 100644 --- a/packages/react/src/components/Typography/ErrorMessage/ErrorMessage.tsx +++ b/packages/react/src/components/Typography/ErrorMessage/ErrorMessage.tsx @@ -8,7 +8,7 @@ import classes from './ErrorMessage.module.css'; export type ErrorMessageProps = { /** Changes text sizing */ - size?: 'xsmall' | 'small' | 'medium'; + size?: 'xsmall' | 'small' | 'medium' | 'large'; /** Adds margin-bottom */ spacing?: boolean; /** Toggle error color */ From 4e8052fc6a886b68676ca5de0a47d80eadb93656 Mon Sep 17 00:00:00 2001 From: Michael Marszalek Date: Thu, 21 Sep 2023 12:22:26 +0200 Subject: [PATCH 03/40] feat(Fieldset, Switch, Radio, Checkbox): :sparkles: Add `large` size (#841) --- .../src/components/form/Fieldset/Fieldset.tsx | 17 +++++++---------- .../react/src/components/form/useFormField.ts | 6 ++---- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/packages/react/src/components/form/Fieldset/Fieldset.tsx b/packages/react/src/components/form/Fieldset/Fieldset.tsx index f761062569..6716367d70 100644 --- a/packages/react/src/components/form/Fieldset/Fieldset.tsx +++ b/packages/react/src/components/form/Fieldset/Fieldset.tsx @@ -5,17 +5,15 @@ import { PadlockLockedFillIcon } from '@navikt/aksel-icons'; import { Label, Paragraph, ErrorMessage } from '../../Typography'; import utilityclasses from '../../../utils/utility.module.css'; +import type { FormFieldProps } from '../useFormField'; import { useFieldset } from './useFieldset'; import classes from './Fieldset.module.css'; -export type FieldsetContextType = { - error?: ReactNode; - errorId?: string; - disabled?: boolean; - readOnly?: boolean; - size?: 'xsmall' | 'small' | 'medium'; -}; +export type FieldsetContextType = Pick< + FormFieldProps, + 'error' | 'errorId' | 'disabled' | 'readOnly' | 'size' +>; export const FieldsetContext = createContext(null); @@ -28,14 +26,13 @@ export type FieldsetProps = { error?: ReactNode; /** The legend of the fieldset. */ legend?: ReactNode; - /** The size of the fieldset. */ - size?: 'xsmall' | 'small' | 'medium'; /** Toggle `readOnly` on fieldset context. * @note This does not prevent fieldset values from being submited */ readOnly?: boolean; /** Visually hide `legend` and `description` (still available for screen readers) */ hideLegend?: boolean; -} & FieldsetHTMLAttributes; +} & Pick & + FieldsetHTMLAttributes; export const Fieldset = forwardRef( (props, ref) => { diff --git a/packages/react/src/components/form/useFormField.ts b/packages/react/src/components/form/useFormField.ts index e44806270d..ef65fda379 100644 --- a/packages/react/src/components/form/useFormField.ts +++ b/packages/react/src/components/form/useFormField.ts @@ -20,7 +20,7 @@ export type FormFieldProps = { /** Toggle `readOnly` */ readOnly?: boolean; /** Changes field size and paddings */ - size?: 'xsmall' | 'small' | 'medium'; + size?: 'xsmall' | 'small' | 'medium' | 'large'; } & Pick, 'aria-describedby'>; export type FormField = { @@ -31,9 +31,7 @@ export type FormField = { InputHTMLAttributes, 'id' | 'disabled' | 'aria-invalid' | 'aria-describedby' >; - readOnly?: boolean; - size?: 'xsmall' | 'small' | 'medium'; -}; +} & Pick; /** * Handles props and their state for various form-fields in context with Fieldset From 0c14cfa3c6add379ada2f5e11dd2b6a0de05aa56 Mon Sep 17 00:00:00 2001 From: Michael Marszalek Date: Thu, 21 Sep 2023 12:34:22 +0200 Subject: [PATCH 04/40] feat(Textfield): :sparkles: New `Textfield` component (#816) --- packages/Overview.mdx | 2 +- .../src/components/form/CharacterCounter.tsx | 62 ++++++ .../form/Textfield/TextField.test.tsx | 145 +++++++++++++ .../components/form/Textfield/Textfield.mdx | 18 ++ .../form/Textfield/Textfield.module.css | 111 ++++++++++ .../form/Textfield/Textfield.stories.tsx | 56 +++++ .../components/form/Textfield/Textfield.tsx | 198 ++++++++++++++++++ .../src/components/form/Textfield/index.ts | 1 + .../components/form/Textfield/useTextfield.ts | 44 ++++ packages/react/src/components/index.ts | 1 + 10 files changed, 637 insertions(+), 1 deletion(-) create mode 100644 packages/react/src/components/form/CharacterCounter.tsx create mode 100644 packages/react/src/components/form/Textfield/TextField.test.tsx create mode 100644 packages/react/src/components/form/Textfield/Textfield.mdx create mode 100644 packages/react/src/components/form/Textfield/Textfield.module.css create mode 100644 packages/react/src/components/form/Textfield/Textfield.stories.tsx create mode 100644 packages/react/src/components/form/Textfield/Textfield.tsx create mode 100644 packages/react/src/components/form/Textfield/index.ts create mode 100644 packages/react/src/components/form/Textfield/useTextfield.ts diff --git a/packages/Overview.mdx b/packages/Overview.mdx index 03257946e0..bc0dfdb2a6 100644 --- a/packages/Overview.mdx +++ b/packages/Overview.mdx @@ -41,7 +41,7 @@ V1 er klar når følgende komponenter er markert som "✅ Felles": | [Tabs](/docs/altinn-tabs--docs) | 🔵 Altinn | [Figma - Tabs](https://www.figma.com/file/vpM9dqqQPHqU6ogfKp5tlr/Felles-komponenter?type=design&node-id=9551%3A54208&t=Rlfq5UyNZBL69dFr-1) | [Github - Tabs](https://github.com/digdir/designsystem/issues/91) | | [Tag](/docs/felles-tag--docs) | ✅ Felles | [Figma - Tag](https://www.figma.com/file/vpM9dqqQPHqU6ogfKp5tlr/Felles-komponenter?node-id=10185%3A59053&t=7Q2N4sUdQGhFZrPh-1) | [Github - Tag](https://github.com/digdir/designsystem/issues/322) | | [Textarea](/docs/altinn-textarea--docs) | 🔵 Altinn | [Figma - Text area](https://www.figma.com/file/vpM9dqqQPHqU6ogfKp5tlr/Felles-komponenter?node-id=6632%3A21873&t=7Q2N4sUdQGhFZrPh-1) | [Github - Textarea](https://github.com/digdir/designsystem/issues/323) | -| [Textfield](/docs/altinn-textfield--docs) | 🔵 Altinn | [Figma - Text Field](https://www.figma.com/file/vpM9dqqQPHqU6ogfKp5tlr/Felles-komponenter?node-id=6632%3A22228&t=7Q2N4sUdQGhFZrPh-1) | [Github - Textfield](https://github.com/digdir/designsystem/issues/92) | +| [Textfield](/docs/felles-textfield--docs) | ✅ Felles | [Figma - Text Field](https://www.figma.com/file/vpM9dqqQPHqU6ogfKp5tlr/Felles-komponenter?node-id=6632%3A22228&t=7Q2N4sUdQGhFZrPh-1) | [Github - Textfield](https://github.com/digdir/designsystem/issues/92) | | [ToggleGroup](/docs/altinn-togglebuttongroup--docs) | 🔵 Altinn | Figma - Toggle Group | [Github - ToggleGroup](https://github.com/digdir/designsystem/issues/304) | | Tooltip | 🚸 Ikke påbegynt | Figma - Tooltip | [Github - Tooltip](https://github.com/digdir/designsystem/issues/93) | | [Typography](/docs/felles-typography--docs) | ✅ Felles | [Figma - Typography](https://www.figma.com/file/vpM9dqqQPHqU6ogfKp5tlr/Felles-komponenter?node-id=9219%3A49405&t=7Q2N4sUdQGhFZrPh-1) | [Github - Typography](https://github.com/digdir/designsystem/issues/324) | diff --git a/packages/react/src/components/form/CharacterCounter.tsx b/packages/react/src/components/form/CharacterCounter.tsx new file mode 100644 index 0000000000..c123211dfc --- /dev/null +++ b/packages/react/src/components/form/CharacterCounter.tsx @@ -0,0 +1,62 @@ +import React from 'react'; + +import utilityClasses from '../../utils/utility.module.css'; +import { ErrorMessage } from '../Typography'; + +export type CharacterLimitProps = Omit< + CharacterCounterProps, + 'id' | 'value' | 'size' +>; + +type CharacterCounterProps = { + /** The message indicating the remaining character limit. */ + label?: (count: number) => string; + /** The description of the maximum character limit for screen readers. */ + srLabel?: string; + /** The maximum allowed character count. */ + maxCount: number; + /** The current value. */ + value: string; + /** The ID of the element that describes the maximum character limit for accessibility purposes. */ + id: string; + /** Text size */ + size?: 'xsmall' | 'small' | 'medium' | 'large'; +}; + +const defaultLabel: CharacterCounterProps['label'] = (count) => + count > -1 ? `${count} tegn igjen` : `${Math.abs(count)} tegn for mye`; + +const defaultSrLabel = (maxCount: number) => + `Tekstfelt med plass til ${maxCount} tegn`; + +export const CharacterCounter = ({ + label = defaultLabel, + srLabel: propsSrLabel, + maxCount, + value, + id, + size, +}: CharacterCounterProps): JSX.Element => { + const currentCount = maxCount - value.length; + const hasExceededLimit = value.length > maxCount; + const srLabel = propsSrLabel ? propsSrLabel : defaultSrLabel(maxCount); + + return ( + <> + + {srLabel} + + + {label(currentCount)} + + + ); +}; diff --git a/packages/react/src/components/form/Textfield/TextField.test.tsx b/packages/react/src/components/form/Textfield/TextField.test.tsx new file mode 100644 index 0000000000..3192022358 --- /dev/null +++ b/packages/react/src/components/form/Textfield/TextField.test.tsx @@ -0,0 +1,145 @@ +import { render as renderRtl, screen } from '@testing-library/react'; +import React from 'react'; +import userEvent from '@testing-library/user-event'; + +import type { TextfieldProps } from './Textfield'; +import { Textfield } from './Textfield'; + +const user = userEvent.setup(); + +describe('TextField', () => { + test('has correct value and label', () => { + render({ value: 'test', label: 'label' }); + expect(screen.getByLabelText('label')).toBeDefined(); + expect(screen.getByDisplayValue('test')).toBeDefined(); + }); + + test('has correct description', () => { + render({ description: 'description' }); + expect( + screen.getByRole('textbox', { description: 'description' }), + ).toBeDefined(); + }); + + test('has correct description and label when label is hidden', () => { + render({ description: 'description', label: 'label', hideLabel: true }); + + expect(screen.getByLabelText('label')).toBeDefined(); + expect( + screen.getByRole('textbox', { description: 'description' }), + ).toBeDefined(); + }); + + test('is invalid with correct error message', () => { + render({ error: 'error-message' }); + + const input = screen.getByRole('textbox', { description: 'error-message' }); + expect(input).toBeDefined(); + expect(input).toBeInvalid(); + }); + test('is invalid with correct error message from errorId', () => { + renderRtl( + <> + my error message + + , + ); + + const input = screen.getByRole('textbox', { + description: 'my error message', + }); + expect(input).toBeDefined(); + expect(input).toBeInvalid(); + }); + it('should have max allowed characters label for screen readers', () => { + render({ + characterLimit: { + maxCount: 10, + srLabel: 'Max 10 characters is allowed', + label: (count: number) => `${count} characters remaining`, + }, + }); + const screenReaderText = screen.getByText('Max 10 characters is allowed'); + expect(screenReaderText).toBeInTheDocument(); + }); + + it('should countdown remaining characters', async () => { + const user = userEvent.setup(); + render({ + label: 'First name', + characterLimit: { + maxCount: 10, + label: (count: number) => `${count} characters remaining`, + srLabel: 'characters remaining', + }, + }); + const inputField = screen.getByLabelText('First name'); + await user.type(inputField, 'Peter'); + expect(screen.getByText('5 characters remaining')).toBeInTheDocument(); + }); + + it('Triggers onBlur event when field loses focus', async () => { + const onBlur = jest.fn(); + render({ onBlur }); + const element = screen.getByRole('textbox'); + await user.click(element); + expect(element).toHaveFocus(); + await user.tab(); + expect(onBlur).toHaveBeenCalledTimes(1); + }); + + it('Triggers onChange event for each keystroke', async () => { + const onChange = jest.fn(); + const data = 'test'; + render({ onChange }); + const element = screen.getByRole('textbox'); + await user.click(element); + expect(element).toHaveFocus(); + await user.keyboard(data); + expect(onChange).toHaveBeenCalledTimes(data.length); + }); + + it('Sets given id on input field', () => { + const id = 'some-unique-id'; + render({ id }); + expect(screen.getByRole('textbox')).toHaveAttribute('id', id); + }); + + it('Focuses on input field when label is clicked and id is not given', async () => { + const label = 'Lorem ipsum'; + render({ label }); + await user.click(screen.getByText(label)); + expect(screen.getByRole('textbox')).toHaveFocus(); + }); + + it('Focuses on input field when label is clicked and id is given', async () => { + const label = 'Lorem ipsum'; + render({ id: 'some-unique-id', label }); + await user.click(screen.getByText(label)); + expect(screen.getByRole('textbox')).toHaveFocus(); + }); + + it('Has type attribute set to "text" by default', () => { + render(); + expect(screen.getByRole('textbox')).toHaveAttribute('type', 'text'); + }); + + it('Has given type attribute if set', () => { + const type = 'tel'; + render({ type }); + expect(screen.getByRole('textbox')).toHaveAttribute('type', type); + }); +}); + +const render = (props: Partial = {}) => + renderRtl( + , + ); diff --git a/packages/react/src/components/form/Textfield/Textfield.mdx b/packages/react/src/components/form/Textfield/Textfield.mdx new file mode 100644 index 0000000000..be79a1b322 --- /dev/null +++ b/packages/react/src/components/form/Textfield/Textfield.mdx @@ -0,0 +1,18 @@ +import { Meta, Canvas, Story, Controls, Primary } from '@storybook/blocks'; +import { Information } from '../../../../../../docs-components'; +import * as TextfieldStories from './Textfield.stories'; + + + +# Textfield + + + + +## Antall tegn + + + +## Kontrollert + + diff --git a/packages/react/src/components/form/Textfield/Textfield.module.css b/packages/react/src/components/form/Textfield/Textfield.module.css new file mode 100644 index 0000000000..075537dcf8 --- /dev/null +++ b/packages/react/src/components/form/Textfield/Textfield.module.css @@ -0,0 +1,111 @@ +.textfield { + display: grid; + gap: var(--fds-spacing-1); +} + +.adornment { + color: var(--fds-semantic-border-neutral-default); + background: var(--fds-semantic-surface-neutral-subtle); + padding: var(--fds-spacing-3); + border-radius: var(--fds-border_radius-medium); + border: solid 1px var(--fds-semantic-border-neutral-default); + box-sizing: border-box; + display: inline-block; +} + +.label { + min-width: min-content; + display: inline-flex; + flex-direction: row; + gap: var(--fds-spacing-1); + align-items: center; +} + +.description { + color: var(--fds-semantic-text-neutral-subtle); +} + +.input { + font: inherit; + position: relative; + box-sizing: border-box; + flex: 0 1 auto; + min-height: 2.5em; + width: 100%; + appearance: none; + padding: 0 var(--fds-spacing-3); + border: solid 1px var(--fds-semantic-border-action-dark); + border-radius: var(--fds-border_radius-medium); +} + +.disabled { + opacity: 0.3; +} + +.disabled .input { + cursor: not-allowed; +} + +.readonly .input { + background: var(--fds-semantic-surface-neutral-subtle); + border-color: var(--fds-semantic-border-neutral-default); +} + +.error > .input:not(:focus-visible) { + border-color: var(--fds-semantic-border-danger-default); + box-shadow: inset 0 0 0 1px var(--fds-semantic-border-danger-default); +} + +@media (hover: hover) and (pointer: fine) { + .input:not(:focus-visible, :disabled):hover { + border-color: var(--fds-semantic-border-action-hover); + box-shadow: inset 0 0 0 1px var(--fds-semantic-border-action-hover); + } +} + +.inputPrefix { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.inputSufix { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.prefix { + border-right: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.sufix { + border-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.field { + display: flex; + align-items: stretch; + border-radius: var(--fds-border_radius-medium); +} + +.field > *:first-child { + border-top-left-radius: var(--fds-border_radius-medium); + border-bottom-left-radius: var(--fds-border_radius-medium); +} + +.field > *:last-child { + border-top-right-radius: var(--fds-border_radius-medium); + border-bottom-right-radius: var(--fds-border_radius-medium); +} + +.padlock { + height: 1.2rem; + width: 1.2rem; +} + +.errorMessage:empty { + display: none; +} diff --git a/packages/react/src/components/form/Textfield/Textfield.stories.tsx b/packages/react/src/components/form/Textfield/Textfield.stories.tsx new file mode 100644 index 0000000000..67c241e2c0 --- /dev/null +++ b/packages/react/src/components/form/Textfield/Textfield.stories.tsx @@ -0,0 +1,56 @@ +import type { Meta, StoryObj, StoryFn } from '@storybook/react'; +import React, { useState } from 'react'; + +import { Button, Paragraph } from '../..'; + +import { Textfield } from '.'; + +type Story = StoryObj; + +export default { + title: 'Felles/Textfield', + component: Textfield, +} as Meta; + +export const Preview: Story = { + args: { + label: 'Label', + disabled: false, + readOnly: false, + size: 'medium', + description: '', + }, +}; + +export const WithCharacterCounter: Story = { + args: { + label: 'Label', + characterLimit: { + maxCount: 5, + }, + }, +}; + +export const Controlled: StoryFn = () => { + const [value, setValue] = useState(); + return ( + <> + Du har skrevet inn: {value} +
+ setValue(e.target.value)} + /> + +
+ + ); +}; diff --git a/packages/react/src/components/form/Textfield/Textfield.tsx b/packages/react/src/components/form/Textfield/Textfield.tsx new file mode 100644 index 0000000000..448eb1e0ad --- /dev/null +++ b/packages/react/src/components/form/Textfield/Textfield.tsx @@ -0,0 +1,198 @@ +import type { InputHTMLAttributes, ReactNode } from 'react'; +import React, { useState, useId, forwardRef } from 'react'; +import cn from 'classnames'; +import { PadlockLockedFillIcon } from '@navikt/aksel-icons'; + +import { omit } from '../../../utils'; +import { Label, Paragraph, ErrorMessage } from '../../Typography'; +import type { FormFieldProps } from '../useFormField'; +import type { CharacterLimitProps } from '../CharacterCounter'; +import { CharacterCounter } from '../CharacterCounter'; + +import { useTextfield } from './useTextfield'; +import classes from './Textfield.module.css'; +import utilityClasses from './../../../utils/utility.module.css'; + +export type TextfieldProps = { + /** Label */ + label?: ReactNode; + /** Visually hides `label` and `description` (still available for screen readers) */ + hideLabel?: boolean; + /** Changes field size and paddings */ + size?: 'xsmall' | 'small' | 'medium' | 'large'; + /** Prefix for field. */ + prefix?: string; + /** Sufix for field. */ + sufix?: string; + /** Supported `input` types */ + type?: + | 'date' + | 'datetime-local' + | 'email' + | 'file' + | 'month' + | 'number' + | 'password' + | 'search' + | 'tel' + | 'text' + | 'time' + | 'url' + | 'week'; + /** + * The characterLimit function calculates remaining characters based on `maxCount` + * + * Provide a `label` function that takes count as parameter and returns a message. + * + * Use `srLabel` to describe `maxCount` for screen readers. + * + * Defaults to Norwegian if no labels are provided. + */ + characterLimit?: CharacterLimitProps; +} & Omit & + Omit, 'size'>; + +/** Text input field + * + * @example + * ```tsx + * + * ``` + */ +export const Textfield = forwardRef( + (props, ref) => { + const { + label, + description, + sufix, + prefix, + style, + characterLimit, + hideLabel, + type = 'text', + ...rest + } = props; + + const { + inputProps, + descriptionId, + hasError, + errorId, + size = 'medium', + readOnly, + } = useTextfield(props); + + const [inputValue, setInputValue] = useState(props.defaultValue); + const characterLimitId = `textfield-charactercount-${useId()}`; + const hasCharacterLimit = characterLimit != null; + + const describedBy = cn( + inputProps['aria-describedby'], + hasCharacterLimit && characterLimitId, + ); + + return ( + + {label && ( + + )} + {description && ( + + {description} + + )} +
+ {prefix && ( + + )} + { + inputProps?.onChange?.(e); + setInputValue(e.target.value); + }} + /> + {sufix && ( + + )} +
+ {hasCharacterLimit && ( + + )} +
+ {hasError && {props.error}} +
+
+ ); + }, +); diff --git a/packages/react/src/components/form/Textfield/index.ts b/packages/react/src/components/form/Textfield/index.ts new file mode 100644 index 0000000000..4ece73e0b9 --- /dev/null +++ b/packages/react/src/components/form/Textfield/index.ts @@ -0,0 +1 @@ +export * from './Textfield'; diff --git a/packages/react/src/components/form/Textfield/useTextfield.ts b/packages/react/src/components/form/Textfield/useTextfield.ts new file mode 100644 index 0000000000..d3e50c436a --- /dev/null +++ b/packages/react/src/components/form/Textfield/useTextfield.ts @@ -0,0 +1,44 @@ +import type { InputHTMLAttributes } from 'react'; +import { useContext } from 'react'; + +import type { FormField } from '../useFormField'; +import { useFormField } from '../useFormField'; +import { FieldsetContext } from '../Fieldset'; + +import type { TextfieldProps } from './Textfield'; + +type UseTextfield = (props: TextfieldProps) => FormField & { + inputProps?: Pick< + InputHTMLAttributes, + 'readOnly' | 'type' | 'name' | 'required' | 'onClick' | 'onChange' + >; +}; +/** Handles props for `Textfield` in context with `Fieldset` */ +export const useTextfield: UseTextfield = (props) => { + const fieldset = useContext(FieldsetContext); + const { inputProps, readOnly, ...rest } = useFormField(props, 'textfield'); + + return { + ...rest, + readOnly, + size: fieldset?.size ?? props.size, + inputProps: { + ...inputProps, + readOnly, + onClick: (e) => { + if (readOnly) { + e.preventDefault(); + return; + } + props?.onClick?.(e); + }, + onChange: (e) => { + if (readOnly) { + e.preventDefault(); + return; + } + props?.onChange?.(e); + }, + }, + }; +}; diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts index 58a7d47ecb..71eb4e5dd5 100644 --- a/packages/react/src/components/index.ts +++ b/packages/react/src/components/index.ts @@ -27,3 +27,4 @@ export * from './form/Checkbox'; export * from './form/Radio'; export * from './form/Fieldset'; export * from './form/Switch'; +export * from './form/Textfield'; From c3d6d2d684ff764fe96a92e1852ddf115cf1ec62 Mon Sep 17 00:00:00 2001 From: Michael Marszalek Date: Thu, 21 Sep 2023 12:47:46 +0200 Subject: [PATCH 05/40] =?UTF-8?q?feat(TextField):=20=F0=9F=97=91=EF=B8=8F?= =?UTF-8?q?=20Change=20to=20Legacy=20(#838)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/components/TextField/index.ts | 2 -- packages/react/src/components/index.ts | 2 +- .../legacy/LegacyCheckbox/Checkbox.mdx | 2 +- .../CheckboxGroup.stories.mdx | 2 +- .../LegacyCheckboxGroup/CheckboxGroup.tsx | 5 ++++ .../legacy/LegacyFieldSet/FieldSet.mdx | 2 +- .../LegacyFieldSet/FieldSet.stories.tsx | 6 ++--- .../legacy/LegacyFieldSet/FieldSet.tsx | 2 +- .../LegacyRadioButton/RadioButton.stories.mdx | 2 +- .../legacy/LegacyRadioButton/RadioButton.tsx | 2 +- .../LegacyRadioGroup/RadioGroup.stories.mdx | 2 +- .../legacy/LegacyRadioGroup/RadioGroup.tsx | 2 +- .../LegacyTextField}/TextField.mdx | 13 ++++++---- .../LegacyTextField}/TextField.stories.tsx | 16 ++++++------ .../LegacyTextField}/TextField.test.tsx | 12 ++++----- .../LegacyTextField}/TextField.tsx | 25 +++++++++++++------ .../legacy/LegacyTextField/index.ts | 5 ++++ 17 files changed, 61 insertions(+), 41 deletions(-) delete mode 100644 packages/react/src/components/TextField/index.ts rename packages/react/src/components/{TextField => legacy/LegacyTextField}/TextField.mdx (78%) rename packages/react/src/components/{TextField => legacy/LegacyTextField}/TextField.stories.tsx (78%) rename packages/react/src/components/{TextField => legacy/LegacyTextField}/TextField.test.tsx (97%) rename packages/react/src/components/{TextField => legacy/LegacyTextField}/TextField.tsx (90%) create mode 100644 packages/react/src/components/legacy/LegacyTextField/index.ts diff --git a/packages/react/src/components/TextField/index.ts b/packages/react/src/components/TextField/index.ts deleted file mode 100644 index 03fca4ab6a..0000000000 --- a/packages/react/src/components/TextField/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { TextField } from './TextField'; -export type { TextFieldProps, TextFieldFormatting } from './TextField'; diff --git a/packages/react/src/components/index.ts b/packages/react/src/components/index.ts index 71eb4e5dd5..809d019ddf 100644 --- a/packages/react/src/components/index.ts +++ b/packages/react/src/components/index.ts @@ -3,6 +3,7 @@ export * from './legacy/LegacyCheckbox'; export * from './legacy/LegacyCheckboxGroup'; export * from './legacy/LegacyRadioButton'; export * from './legacy/LegacyRadioGroup'; +export * from './legacy/LegacyTextField'; export * from './Button'; export * from './Tabs'; @@ -11,7 +12,6 @@ export * from './Popover'; export * from './Select'; export * from './Spinner'; export * from './TextArea'; -export * from './TextField'; export * from './Link'; export * from './List'; export * from './Table'; diff --git a/packages/react/src/components/legacy/LegacyCheckbox/Checkbox.mdx b/packages/react/src/components/legacy/LegacyCheckbox/Checkbox.mdx index c45b029f4c..5595236ed3 100644 --- a/packages/react/src/components/legacy/LegacyCheckbox/Checkbox.mdx +++ b/packages/react/src/components/legacy/LegacyCheckbox/Checkbox.mdx @@ -10,7 +10,7 @@ import { Controls, Primary } from '@storybook/blocks'; `LegacyCheckbox` er en boks som brukeren kan krysse av i for bolske verdier. Den kan også brukes i en gruppe hvor brukeren kan velge flere verdier. diff --git a/packages/react/src/components/legacy/LegacyCheckboxGroup/CheckboxGroup.stories.mdx b/packages/react/src/components/legacy/LegacyCheckboxGroup/CheckboxGroup.stories.mdx index 59b8630d5e..830b2fb1cb 100644 --- a/packages/react/src/components/legacy/LegacyCheckboxGroup/CheckboxGroup.stories.mdx +++ b/packages/react/src/components/legacy/LegacyCheckboxGroup/CheckboxGroup.stories.mdx @@ -80,7 +80,7 @@ export const Template = (args = {}) => ( `LegacyCheckboxGroup` er en gruppe med sjekkbokser som gir brukeren mulighet til å velge flere verdier i en liste. diff --git a/packages/react/src/components/legacy/LegacyCheckboxGroup/CheckboxGroup.tsx b/packages/react/src/components/legacy/LegacyCheckboxGroup/CheckboxGroup.tsx index 12408ca572..746748afac 100644 --- a/packages/react/src/components/legacy/LegacyCheckboxGroup/CheckboxGroup.tsx +++ b/packages/react/src/components/legacy/LegacyCheckboxGroup/CheckboxGroup.tsx @@ -136,4 +136,9 @@ const LegacyCheckboxGroup = ({ LegacyCheckboxGroup.displayName = 'LegacyCheckboxGroup'; +/** + * + * @note + * Replaced by new {@link https://digdir.github.io/designsystem/?path=/docs/felles-checkbox-group--docs Checkbox.Group} component. + */ export { LegacyCheckboxGroup }; diff --git a/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.mdx b/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.mdx index ad3e2ad41f..18e048ec67 100644 --- a/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.mdx +++ b/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.mdx @@ -8,7 +8,7 @@ import * as FieldSetStories from './FieldSet.stories'; `LegacyFieldSet` brukes til å gruppere innhold i et skjema. diff --git a/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.stories.tsx b/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.stories.tsx index 447273904f..d19d8e1ca7 100644 --- a/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.stories.tsx +++ b/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.stories.tsx @@ -1,7 +1,7 @@ import React from 'react'; import type { Meta, StoryFn } from '@storybook/react'; -import { TextField } from '../../TextField'; +import { LegacyTextField } from '../LegacyTextField'; import { LegacyFieldSet } from './FieldSet'; @@ -13,8 +13,8 @@ export default { export const Eksempel: StoryFn = (args) => (
- - + diff --git a/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.tsx b/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.tsx index ca29fb8465..629003da94 100644 --- a/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.tsx +++ b/packages/react/src/components/legacy/LegacyFieldSet/FieldSet.tsx @@ -38,7 +38,7 @@ export type LegacyFieldSetProps = { /** * * @note - * Will be replaced by new Fieldset component. + * Replaced by new {@link https://digdir.github.io/designsystem/?path=/docs/felles-fieldset--docs Fieldset} component. */ const LegacyFieldSet = forwardRef( ( diff --git a/packages/react/src/components/legacy/LegacyRadioButton/RadioButton.stories.mdx b/packages/react/src/components/legacy/LegacyRadioButton/RadioButton.stories.mdx index 72b5a1f3dc..306501ad76 100644 --- a/packages/react/src/components/legacy/LegacyRadioButton/RadioButton.stories.mdx +++ b/packages/react/src/components/legacy/LegacyRadioButton/RadioButton.stories.mdx @@ -81,7 +81,7 @@ export const Template = (args = {}) => ( `LegacyRadioButton` er en knapp som skal brukes i kombinasjon med andre radioknapper for å velge mellom flere alternativer. diff --git a/packages/react/src/components/legacy/LegacyRadioButton/RadioButton.tsx b/packages/react/src/components/legacy/LegacyRadioButton/RadioButton.tsx index e4ab7b4d28..db9e00b493 100644 --- a/packages/react/src/components/legacy/LegacyRadioButton/RadioButton.tsx +++ b/packages/react/src/components/legacy/LegacyRadioButton/RadioButton.tsx @@ -26,7 +26,7 @@ export interface LegacyRadioButtonProps { /** * * @note - * Will be replaced by new {@link https://digdir.github.io/designsystem/?path=/docs/felles-radio--docs Radio} component. + * Replaced by new {@link https://digdir.github.io/designsystem/?path=/docs/felles-radio--docs Radio} component. */ const LegacyRadioButton = forwardRef( ( diff --git a/packages/react/src/components/legacy/LegacyRadioGroup/RadioGroup.stories.mdx b/packages/react/src/components/legacy/LegacyRadioGroup/RadioGroup.stories.mdx index 732d59f64a..385702fbef 100644 --- a/packages/react/src/components/legacy/LegacyRadioGroup/RadioGroup.stories.mdx +++ b/packages/react/src/components/legacy/LegacyRadioGroup/RadioGroup.stories.mdx @@ -83,7 +83,7 @@ export const Template = (args = {}) => ( `LegacyRadioGroup` er en gruppe med radioknapper som gir brukeren mulighet til å velge ett av flere alternativer. diff --git a/packages/react/src/components/legacy/LegacyRadioGroup/RadioGroup.tsx b/packages/react/src/components/legacy/LegacyRadioGroup/RadioGroup.tsx index fe2d76f6a7..84ab3125e2 100644 --- a/packages/react/src/components/legacy/LegacyRadioGroup/RadioGroup.tsx +++ b/packages/react/src/components/legacy/LegacyRadioGroup/RadioGroup.tsx @@ -33,7 +33,7 @@ export interface LegacyRadioGroupProps { /** * * @note - * Will be replaced by new {@link https://digdir.github.io/designsystem/?path=/docs/felles-radio-group--docs Radio.Group} component. + * Replaced by new {@link https://digdir.github.io/designsystem/?path=/docs/felles-radio-group--docs Radio.Group} component. */ const LegacyRadioGroup = ({ description, diff --git a/packages/react/src/components/TextField/TextField.mdx b/packages/react/src/components/legacy/LegacyTextField/TextField.mdx similarity index 78% rename from packages/react/src/components/TextField/TextField.mdx rename to packages/react/src/components/legacy/LegacyTextField/TextField.mdx index 4f3c9630ce..b2be251506 100644 --- a/packages/react/src/components/TextField/TextField.mdx +++ b/packages/react/src/components/legacy/LegacyTextField/TextField.mdx @@ -1,23 +1,26 @@ import { Meta, Canvas, Story, Primary, Controls } from '@storybook/blocks'; import { TextField } from './'; -import { Information, TokensTable } from '../../../../../docs-components'; +import { Information, TokensTable } from '../../../../../../docs-components'; import { ArgsTable } from '@storybook/blocks'; import * as TextFieldStories from './TextField.stories'; -# TextField +# LegacyTextField - + `TextField` er en tekstboks som tar imot korte, rene tekster uten linjeskift. For lengre tekster, bruk `TextArea`. ## Bruk ```tsx -import { TextField } from '@digdir/design-system-react'; +import { LegacyTextField } from '@digdir/design-system-react'; -; +; ``` ## Props diff --git a/packages/react/src/components/TextField/TextField.stories.tsx b/packages/react/src/components/legacy/LegacyTextField/TextField.stories.tsx similarity index 78% rename from packages/react/src/components/TextField/TextField.stories.tsx rename to packages/react/src/components/legacy/LegacyTextField/TextField.stories.tsx index a9808d2f7c..4082a8074d 100644 --- a/packages/react/src/components/TextField/TextField.stories.tsx +++ b/packages/react/src/components/legacy/LegacyTextField/TextField.stories.tsx @@ -1,20 +1,20 @@ import type { Meta, StoryObj } from '@storybook/react'; import React from 'react'; -import type { TextFieldProps } from '.'; -import { TextField } from '.'; +import type { LegacyTextFieldProps } from '.'; +import { LegacyTextField } from '.'; -type Story = StoryObj; +type Story = StoryObj; -const meta: Meta = { - title: 'Altinn/TextField', - component: TextField, +const meta: Meta = { + title: 'Avviklet/LegacyTextField', + component: LegacyTextField, }; export default meta; -const createTemplate = (name: string, args?: TextFieldProps): Story => ({ - render: (args) => , +const createTemplate = (name: string, args?: LegacyTextFieldProps): Story => ({ + render: (args) => , args, name, }); diff --git a/packages/react/src/components/TextField/TextField.test.tsx b/packages/react/src/components/legacy/LegacyTextField/TextField.test.tsx similarity index 97% rename from packages/react/src/components/TextField/TextField.test.tsx rename to packages/react/src/components/legacy/LegacyTextField/TextField.test.tsx index eeb39582f9..ebd477d023 100644 --- a/packages/react/src/components/TextField/TextField.test.tsx +++ b/packages/react/src/components/legacy/LegacyTextField/TextField.test.tsx @@ -2,8 +2,8 @@ import { render as renderRtl, screen } from '@testing-library/react'; import React from 'react'; import userEvent from '@testing-library/user-event'; -import type { TextFieldProps } from './TextField'; -import { TextField } from './TextField'; +import type { LegacyTextFieldProps } from './TextField'; +import { LegacyTextField } from './TextField'; const user = userEvent.setup(); @@ -172,7 +172,7 @@ describe('TextField', () => { expect(screen.getByDisplayValue('$1 234')).toBeInTheDocument(); expect(onChange).not.toHaveBeenCalled(); rerender( - { }); }); -const render = (props: Partial = {}) => { +const render = (props: Partial = {}) => { const allProps = { onChange: jest.fn(), ...props, - } as TextFieldProps; + } as LegacyTextFieldProps; - return renderRtl(); + return renderRtl(); }; diff --git a/packages/react/src/components/TextField/TextField.tsx b/packages/react/src/components/legacy/LegacyTextField/TextField.tsx similarity index 90% rename from packages/react/src/components/TextField/TextField.tsx rename to packages/react/src/components/legacy/LegacyTextField/TextField.tsx index 22f10cb4b6..1ec52b5b6f 100644 --- a/packages/react/src/components/TextField/TextField.tsx +++ b/packages/react/src/components/legacy/LegacyTextField/TextField.tsx @@ -9,11 +9,11 @@ import type { } from 'react-number-format'; import { NumericFormat, PatternFormat } from 'react-number-format'; -import { isNumericFormat, isPatternFormat } from '../../utils'; -import { InputWrapper } from '../_InputWrapper'; -import type { ReadOnlyVariant_, CharacterLimit } from '../_InputWrapper'; +import { isNumericFormat, isPatternFormat } from '../../../utils'; +import { InputWrapper } from '../../_InputWrapper'; +import type { ReadOnlyVariant_, CharacterLimit } from '../../_InputWrapper'; -export type TextFieldProps = { +export type LegacyTextFieldProps = { /** * The characterLimit function calculates remaining characters. * Provide a `label` function that takes count as parameter and returns a message. @@ -25,7 +25,7 @@ export type TextFieldProps = { defaultValue?: string | number; /** The formatting options for the text field. */ - formatting?: TextFieldFormatting; + formatting?: LegacyTextFieldFormatting; /** Specifies whether the value of the text field is valid. */ isValid?: boolean; @@ -65,7 +65,7 @@ export type TextFieldProps = { 'readOnly' | 'value' | 'defaultValue' | 'type' >; // Todo: We should extend the props of here, but it's complex because of the number format implementation. We should move that out to a separate component first. -export type TextFieldFormatting = { +export type LegacyTextFieldFormatting = { align?: 'right' | 'center' | 'left'; number?: NumericFormatProps | PatternFormatProps; }; @@ -91,7 +91,16 @@ const replaceTargetValueWithUnformattedValue = ({ }, }; }; -export const TextField = forwardRef( + +/** + * + * @note + * Replaced by new {@link https://digdir.github.io/designsystem/?path=/docs/felles-textfield--docs Textfield} component. + */ +export const LegacyTextField = forwardRef< + HTMLInputElement, + LegacyTextFieldProps +>( ( { id, @@ -107,7 +116,7 @@ export const TextField = forwardRef( characterLimit, 'aria-describedby': ariaDescribedBy, ...rest - }: TextFieldProps, + }: LegacyTextFieldProps, ref: ForwardedRef, ) => { const [currentValue, setCurrentValue] = useState( diff --git a/packages/react/src/components/legacy/LegacyTextField/index.ts b/packages/react/src/components/legacy/LegacyTextField/index.ts new file mode 100644 index 0000000000..521d578804 --- /dev/null +++ b/packages/react/src/components/legacy/LegacyTextField/index.ts @@ -0,0 +1,5 @@ +export { LegacyTextField } from './TextField'; +export type { + LegacyTextFieldProps, + LegacyTextFieldFormatting, +} from './TextField'; From 161e0189e12268b83762a6cf71f506dbce5a45c5 Mon Sep 17 00:00:00 2001 From: Michael Marszalek Date: Thu, 21 Sep 2023 12:49:28 +0200 Subject: [PATCH 06/40] Publish - @digdir/design-system-react@0.25.0 - @digdir/design-system-tokens@0.7.0 --- packages/react/CHANGELOG.md | 10 ++++++++++ packages/react/package.json | 4 ++-- packages/tokens/CHANGELOG.md | 6 ++++++ packages/tokens/package.json | 2 +- yarn.lock | 4 ++-- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 3fe4b08d8f..73b79ac7e8 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.25.0](https://github.com/digdir/designsystem/compare/@digdir/design-system-react@0.24.2...@digdir/design-system-react@0.25.0) (2023-09-21) + +### Features + +- **ErrorMessage:** :sparkles: Add new option to toggle error color ([#836](https://github.com/digdir/designsystem/issues/836)) ([8b177f3](https://github.com/digdir/designsystem/commit/8b177f3f25b3c2075d38f8f5e8a438d8727b5c98)) +- **ErrorMessage:** ✨ Add `large` size ([#840](https://github.com/digdir/designsystem/issues/840)) ([9742abf](https://github.com/digdir/designsystem/commit/9742abf1d002967fdfdb6b3caa8f33bb11a85019)) +- **Fieldset, Switch, Radio, Checkbox:** :sparkles: Add `large` size ([#841](https://github.com/digdir/designsystem/issues/841)) ([4e8052f](https://github.com/digdir/designsystem/commit/4e8052fc6a886b68676ca5de0a47d80eadb93656)) +- **Textfield:** :sparkles: New `Textfield` component ([#816](https://github.com/digdir/designsystem/issues/816)) ([0c14cfa](https://github.com/digdir/designsystem/commit/0c14cfa3c6add379ada2f5e11dd2b6a0de05aa56)) +- **TextField:** 🗑️ Change to Legacy ([#838](https://github.com/digdir/designsystem/issues/838)) ([c3d6d2d](https://github.com/digdir/designsystem/commit/c3d6d2d684ff764fe96a92e1852ddf115cf1ec62)) + ## [0.24.2](https://github.com/digdir/designsystem/compare/@digdir/design-system-react@0.24.1...@digdir/design-system-react@0.24.2) (2023-09-19) ### Bug Fixes diff --git a/packages/react/package.json b/packages/react/package.json index 0702c3156d..b0fb0f7537 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@digdir/design-system-react", - "version": "0.24.2", + "version": "0.25.0", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", "types": "dist/index.d.ts", @@ -23,7 +23,7 @@ }, "dependencies": { "@altinn/figma-design-tokens": "^6.0.1", - "@digdir/design-system-tokens": "^0.6.1", + "@digdir/design-system-tokens": "^0.7.0", "@floating-ui/react": "0.25.2", "@navikt/aksel-icons": "^3.2.4", "react-number-format": "5.2.2" diff --git a/packages/tokens/CHANGELOG.md b/packages/tokens/CHANGELOG.md index a6cbc0864c..5a65a1753f 100644 --- a/packages/tokens/CHANGELOG.md +++ b/packages/tokens/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [0.7.0](https://github.com/digdir/designsystem/compare/@digdir/design-system-tokens@0.6.1...@digdir/design-system-tokens@0.7.0) (2023-09-21) + +### Features + +- **ErrorMessage:** Add Large size token ([#839](https://github.com/digdir/designsystem/issues/839)) ([a5a7739](https://github.com/digdir/designsystem/commit/a5a7739d75de642ea6841b61ca4b719be91856b0)) + ## [0.6.1](https://github.com/digdir/designsystem/compare/@digdir/design-system-tokens@0.6.0...@digdir/design-system-tokens@0.6.1) (2023-09-19) **Note:** Version bump only for package @digdir/design-system-tokens diff --git a/packages/tokens/package.json b/packages/tokens/package.json index 5d76017805..91f8e15f1e 100644 --- a/packages/tokens/package.json +++ b/packages/tokens/package.json @@ -1,6 +1,6 @@ { "name": "@digdir/design-system-tokens", - "version": "0.6.1", + "version": "0.7.0", "description": "Tokens for the Digdir Common Design System", "repository": "https://github.com/digdir/designsystem", "license": "MIT", diff --git a/yarn.lock b/yarn.lock index bd12acd6e4..719f7a9928 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3913,7 +3913,7 @@ __metadata: resolution: "@digdir/design-system-react@workspace:packages/react" dependencies: "@altinn/figma-design-tokens": ^6.0.1 - "@digdir/design-system-tokens": ^0.6.1 + "@digdir/design-system-tokens": ^0.7.0 "@floating-ui/react": 0.25.2 "@navikt/aksel-icons": ^3.2.4 react-number-format: 5.2.2 @@ -3923,7 +3923,7 @@ __metadata: languageName: unknown linkType: soft -"@digdir/design-system-tokens@*, @digdir/design-system-tokens@^0.6.1, @digdir/design-system-tokens@workspace:packages/tokens": +"@digdir/design-system-tokens@*, @digdir/design-system-tokens@^0.7.0, @digdir/design-system-tokens@workspace:packages/tokens": version: 0.0.0-use.local resolution: "@digdir/design-system-tokens@workspace:packages/tokens" dependencies: From 0c59b86f661222e0021311cd5eba6c7aa429ea8c Mon Sep 17 00:00:00 2001 From: Tomas Engebretsen Date: Fri, 22 Sep 2023 08:20:17 +0200 Subject: [PATCH 07/40] fix(Textfield): Prop typo (#848) --- .../components/form/Textfield/Textfield.module.css | 4 ++-- .../{TextField.test.tsx => Textfield.test.tsx} | 2 +- .../src/components/form/Textfield/Textfield.tsx | 14 +++++++------- 3 files changed, 10 insertions(+), 10 deletions(-) rename packages/react/src/components/form/Textfield/{TextField.test.tsx => Textfield.test.tsx} (99%) diff --git a/packages/react/src/components/form/Textfield/Textfield.module.css b/packages/react/src/components/form/Textfield/Textfield.module.css index 075537dcf8..b3a9058f18 100644 --- a/packages/react/src/components/form/Textfield/Textfield.module.css +++ b/packages/react/src/components/form/Textfield/Textfield.module.css @@ -68,7 +68,7 @@ border-bottom-left-radius: 0; } -.inputSufix { +.inputSuffix { border-top-right-radius: 0; border-bottom-right-radius: 0; } @@ -79,7 +79,7 @@ border-bottom-right-radius: 0; } -.sufix { +.suffix { border-left: 0; border-top-left-radius: 0; border-bottom-left-radius: 0; diff --git a/packages/react/src/components/form/Textfield/TextField.test.tsx b/packages/react/src/components/form/Textfield/Textfield.test.tsx similarity index 99% rename from packages/react/src/components/form/Textfield/TextField.test.tsx rename to packages/react/src/components/form/Textfield/Textfield.test.tsx index 3192022358..0b41200576 100644 --- a/packages/react/src/components/form/Textfield/TextField.test.tsx +++ b/packages/react/src/components/form/Textfield/Textfield.test.tsx @@ -7,7 +7,7 @@ import { Textfield } from './Textfield'; const user = userEvent.setup(); -describe('TextField', () => { +describe('Textfield', () => { test('has correct value and label', () => { render({ value: 'test', label: 'label' }); expect(screen.getByLabelText('label')).toBeDefined(); diff --git a/packages/react/src/components/form/Textfield/Textfield.tsx b/packages/react/src/components/form/Textfield/Textfield.tsx index 448eb1e0ad..f644ec96c3 100644 --- a/packages/react/src/components/form/Textfield/Textfield.tsx +++ b/packages/react/src/components/form/Textfield/Textfield.tsx @@ -22,8 +22,8 @@ export type TextfieldProps = { size?: 'xsmall' | 'small' | 'medium' | 'large'; /** Prefix for field. */ prefix?: string; - /** Sufix for field. */ - sufix?: string; + /** Suffix for field. */ + suffix?: string; /** Supported `input` types */ type?: | 'date' @@ -64,7 +64,7 @@ export const Textfield = forwardRef( const { label, description, - sufix, + suffix, prefix, style, characterLimit, @@ -154,7 +154,7 @@ export const Textfield = forwardRef( classes.input, utilityClasses.focusable, prefix && classes.inputPrefix, - sufix && classes.inputSufix, + suffix && classes.inputSuffix, )} ref={ref} type={type} @@ -164,15 +164,15 @@ export const Textfield = forwardRef( setInputValue(e.target.value); }} /> - {sufix && ( + {suffix && ( )}
From 18a2887f2ae228fc8dc18b86e3dd1f007bb6d389 Mon Sep 17 00:00:00 2001 From: Michael Marszalek Date: Fri, 22 Sep 2023 08:24:51 +0200 Subject: [PATCH 08/40] Publish - @digdir/design-system-react@0.25.1 --- packages/react/CHANGELOG.md | 6 ++++++ packages/react/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 73b79ac7e8..71fe088c3d 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.25.1](https://github.com/digdir/designsystem/compare/@digdir/design-system-react@0.25.0...@digdir/design-system-react@0.25.1) (2023-09-22) + +### Bug Fixes + +- **Textfield:** Prop typo ([#848](https://github.com/digdir/designsystem/issues/848)) ([0c59b86](https://github.com/digdir/designsystem/commit/0c59b86f661222e0021311cd5eba6c7aa429ea8c)) + # [0.25.0](https://github.com/digdir/designsystem/compare/@digdir/design-system-react@0.24.2...@digdir/design-system-react@0.25.0) (2023-09-21) ### Features diff --git a/packages/react/package.json b/packages/react/package.json index b0fb0f7537..fd5c86ca78 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@digdir/design-system-react", - "version": "0.25.0", + "version": "0.25.1", "main": "dist/cjs/index.js", "module": "dist/esm/index.js", "types": "dist/index.d.ts", From 4544f1e96fb90c00360377b2a18998e9bce36f16 Mon Sep 17 00:00:00 2001 From: Michael Marszalek Date: Fri, 22 Sep 2023 13:18:57 +0200 Subject: [PATCH 09/40] fix(Textfield): :lipstick: Style adjustments after feedback (#852) --- .../components/form/Textfield/Textfield.mdx | 4 ++++ .../form/Textfield/Textfield.module.css | 18 ++++++++++++++++-- .../form/Textfield/Textfield.stories.tsx | 11 ++++++++++- .../components/form/Textfield/Textfield.tsx | 3 ++- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/packages/react/src/components/form/Textfield/Textfield.mdx b/packages/react/src/components/form/Textfield/Textfield.mdx index be79a1b322..28eedb7072 100644 --- a/packages/react/src/components/form/Textfield/Textfield.mdx +++ b/packages/react/src/components/form/Textfield/Textfield.mdx @@ -16,3 +16,7 @@ import * as TextfieldStories from './Textfield.stories'; ## Kontrollert + +## Full bredde + + diff --git a/packages/react/src/components/form/Textfield/Textfield.module.css b/packages/react/src/components/form/Textfield/Textfield.module.css index b3a9058f18..3557142cda 100644 --- a/packages/react/src/components/form/Textfield/Textfield.module.css +++ b/packages/react/src/components/form/Textfield/Textfield.module.css @@ -1,6 +1,6 @@ -.textfield { +.formField { display: grid; - gap: var(--fds-spacing-1); + gap: var(--fds-spacing-2); } .adornment { @@ -23,6 +23,7 @@ .description { color: var(--fds-semantic-text-neutral-subtle); + margin-top: calc(var(--fds-spacing-2) * -1); } .input { @@ -38,6 +39,19 @@ border-radius: var(--fds-border_radius-medium); } +.input.xsmall, +.input.small { + padding: 0 var(--fds-spacing-2); +} + +.input.medium { + padding: 0 var(--fds-spacing-3); +} + +.input.large { + padding: 0 var(--fds-spacing-4); +} + .disabled { opacity: 0.3; } diff --git a/packages/react/src/components/form/Textfield/Textfield.stories.tsx b/packages/react/src/components/form/Textfield/Textfield.stories.tsx index 67c241e2c0..81c8dd4481 100644 --- a/packages/react/src/components/form/Textfield/Textfield.stories.tsx +++ b/packages/react/src/components/form/Textfield/Textfield.stories.tsx @@ -31,6 +31,15 @@ export const WithCharacterCounter: Story = { }, }; +export const FullWidth: Story = { + args: { + label: 'Label', + }, + parameters: { + layout: 'padded', + }, +}; + export const Controlled: StoryFn = () => { const [value, setValue] = useState(); return ( @@ -49,7 +58,7 @@ export const Controlled: StoryFn = () => { value={value} onChange={(e) => setValue(e.target.value)} /> - + ); diff --git a/packages/react/src/components/form/Textfield/Textfield.tsx b/packages/react/src/components/form/Textfield/Textfield.tsx index f644ec96c3..3337793afd 100644 --- a/packages/react/src/components/form/Textfield/Textfield.tsx +++ b/packages/react/src/components/form/Textfield/Textfield.tsx @@ -97,7 +97,7 @@ export const Textfield = forwardRef( size={size} style={style} className={cn( - classes.textfield, + classes.formField, inputProps.disabled && classes.disabled, readOnly && classes.readonly, rest.className, @@ -152,6 +152,7 @@ export const Textfield = forwardRef( {...inputProps} className={cn( classes.input, + classes[size], utilityClasses.focusable, prefix && classes.inputPrefix, suffix && classes.inputSuffix, From 9d9c3ab390cea40bd3137845fd2b7fb251c84b7a Mon Sep 17 00:00:00 2001 From: Michael Marszalek Date: Fri, 22 Sep 2023 13:38:27 +0200 Subject: [PATCH 10/40] feat(Textarea): :sparkles: New `Textarea` component (#851) --- .../src/components/form/Textarea/Textarea.mdx | 22 +++ .../form/Textarea/Textarea.module.css | 78 ++++++++++ .../form/Textarea/Textarea.stories.tsx | 71 +++++++++ .../form/Textarea/Textarea.test.tsx | 136 ++++++++++++++++ .../src/components/form/Textarea/Textarea.tsx | 145 ++++++++++++++++++ .../src/components/form/Textarea/index.ts | 1 + .../components/form/Textarea/useTextarea.ts | 46 ++++++ .../react/src/components/form/useFormField.ts | 6 +- 8 files changed, 503 insertions(+), 2 deletions(-) create mode 100644 packages/react/src/components/form/Textarea/Textarea.mdx create mode 100644 packages/react/src/components/form/Textarea/Textarea.module.css create mode 100644 packages/react/src/components/form/Textarea/Textarea.stories.tsx create mode 100644 packages/react/src/components/form/Textarea/Textarea.test.tsx create mode 100644 packages/react/src/components/form/Textarea/Textarea.tsx create mode 100644 packages/react/src/components/form/Textarea/index.ts create mode 100644 packages/react/src/components/form/Textarea/useTextarea.ts diff --git a/packages/react/src/components/form/Textarea/Textarea.mdx b/packages/react/src/components/form/Textarea/Textarea.mdx new file mode 100644 index 0000000000..f1c800787c --- /dev/null +++ b/packages/react/src/components/form/Textarea/Textarea.mdx @@ -0,0 +1,22 @@ +import { Meta, Canvas, Story, Controls, Primary } from '@storybook/blocks'; +import { Information } from '../../../../../../docs-components'; +import * as TextareaStories from './Textarea.stories'; + + + +# Textarea + + + + +## Antall tegn + + + +## Kontrollert + + + +## Full bredde + + diff --git a/packages/react/src/components/form/Textarea/Textarea.module.css b/packages/react/src/components/form/Textarea/Textarea.module.css new file mode 100644 index 0000000000..c2f3915f63 --- /dev/null +++ b/packages/react/src/components/form/Textarea/Textarea.module.css @@ -0,0 +1,78 @@ +.formField { + display: grid; + gap: var(--fds-spacing-2); +} + +.padlock { + height: 1.2rem; + width: 1.2rem; +} + +.errorMessage:empty { + display: none; +} + +.label { + min-width: min-content; + display: inline-flex; + flex-direction: row; + gap: var(--fds-spacing-1); + align-items: center; +} + +.description { + color: var(--fds-semantic-text-neutral-subtle); + margin-top: calc(var(--fds-spacing-2) * -1); +} + +.textarea { + font: inherit; + position: relative; + box-sizing: border-box; + flex: 0 1 auto; + min-height: 2.5em; + width: 100%; + appearance: none; + padding: var(--fds-spacing-3); + border: solid 1px var(--fds-semantic-border-action-dark); + border-radius: var(--fds-border_radius-medium); + resize: vertical; +} + +.textarea.xsmall, +.textarea.small { + padding: var(--fds-spacing-2); +} + +.textarea.medium { + padding: var(--fds-spacing-3); +} + +.textarea.large { + padding: var(--fds-spacing-4); +} + +.disabled { + opacity: 0.3; +} + +.disabled .textarea { + cursor: not-allowed; +} + +.readonly .textarea { + background: var(--fds-semantic-surface-neutral-subtle); + border-color: var(--fds-semantic-border-neutral-default); +} + +.error > .textarea:not(:focus-visible) { + border-color: var(--fds-semantic-border-danger-default); + box-shadow: inset 0 0 0 1px var(--fds-semantic-border-danger-default); +} + +@media (hover: hover) and (pointer: fine) { + .textarea:not(:focus-visible, :disabled):hover { + border-color: var(--fds-semantic-border-action-hover); + box-shadow: inset 0 0 0 1px var(--fds-semantic-border-action-hover); + } +} diff --git a/packages/react/src/components/form/Textarea/Textarea.stories.tsx b/packages/react/src/components/form/Textarea/Textarea.stories.tsx new file mode 100644 index 0000000000..ff738ba3e3 --- /dev/null +++ b/packages/react/src/components/form/Textarea/Textarea.stories.tsx @@ -0,0 +1,71 @@ +import type { Meta, StoryObj, StoryFn } from '@storybook/react'; +import React, { useState } from 'react'; + +import { Button, Paragraph } from '../..'; + +import { Textarea } from '.'; + +type Story = StoryObj; + +export default { + title: 'Felles/Textarea', + component: Textarea, +} as Meta; + +export const Preview: Story = { + args: { + label: 'Label', + disabled: false, + readOnly: false, + size: 'medium', + description: '', + error: '', + cols: 40, + }, +}; + +export const WithCharacterCounter: Story = { + args: { + label: 'Label', + cols: 40, + characterLimit: { + maxCount: 5, + }, + }, +}; + +export const FullWidth: Story = { + args: { + label: 'Label', + rows: 10, + cols: 40, + }, + parameters: { + layout: 'padded', + }, +}; + +export const Controlled: StoryFn = () => { + const [value, setValue] = useState(); + return ( + <> + Du har skrevet inn: {value} +
+