@arkitektbedriftene/fe-lib 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkitektbedriftene/fe-lib",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.umd.cjs",
6
6
  "module": "./dist/index.es.js",
@@ -28,6 +28,13 @@
28
28
  "./rich-text": {
29
29
  "import": "./dist/rich-text.es.js",
30
30
  "types": "./dist/rich-text.d.ts"
31
+ },
32
+ "./ui": {
33
+ "import": "./dist/ui.es.js",
34
+ "types": "./dist/ui.d.ts"
35
+ },
36
+ "./ui/ui.css": {
37
+ "import": "./dist/ui.css"
31
38
  }
32
39
  },
33
40
  "repository": {
@@ -51,17 +58,19 @@
51
58
  "@lexical/headless": "^0.12.0",
52
59
  "@lexical/html": "^0.12.0",
53
60
  "@lexical/link": "^0.12.0",
54
- "@lexical/rich-text": "^0.12.0"
61
+ "@lexical/rich-text": "^0.12.0",
62
+ "@types/react": "*",
63
+ "@types/react-dom": "*"
55
64
  },
56
65
  "devDependencies": {
57
- "@types/react": "^18.0.28",
58
- "@types/react-dom": "^18.0.11",
66
+ "@biomejs/biome": "^1.6.2",
59
67
  "@vitejs/plugin-react-swc": "^3.0.0",
60
68
  "typescript": "^4.9.3",
61
69
  "vite": "^4.2.0",
62
70
  "vite-plugin-dts": "^2.1.0"
63
71
  },
64
72
  "dependencies": {
73
+ "@stitches/react": "^1.2.8",
65
74
  "oidc-client-ts": "^2.2.2",
66
75
  "react-icons": "^4.8.0",
67
76
  "use-local-storage-state": "^18.2.1"
@@ -0,0 +1,55 @@
1
+ import { styled } from "../stitches.config";
2
+ import { forwardRef } from "react";
3
+
4
+ const AlertStyled = styled("div", {
5
+ padding: "$3",
6
+ borderRadius: "$md",
7
+
8
+ variants: {
9
+ color: {
10
+ warning: {
11
+ background: "$yellow200",
12
+ color: "#000",
13
+ },
14
+ danger: {
15
+ background: "$red600",
16
+ color: "#fff",
17
+ },
18
+ info: {
19
+ background: "$blue200",
20
+ color: "#000",
21
+ },
22
+ },
23
+ size: {
24
+ sm: {
25
+ fontSize: "$sm",
26
+ },
27
+ md: {
28
+ fontSize: "$md",
29
+ },
30
+ },
31
+ },
32
+
33
+ defaultVariants: {
34
+ color: "info",
35
+ size: "md",
36
+ },
37
+ });
38
+
39
+ type AlertProps = React.ComponentProps<typeof AlertStyled> & {
40
+ as?: React.ElementType;
41
+ }
42
+
43
+ export const Alert = forwardRef<HTMLDivElement, AlertProps>(
44
+ ({ children, ...props }, ref) => {
45
+ return (
46
+ <AlertStyled
47
+ ref={ref}
48
+ role="alert"
49
+ {...props}
50
+ >
51
+ {children}
52
+ </AlertStyled>
53
+ );
54
+ },
55
+ );
@@ -0,0 +1,173 @@
1
+ import { styled } from "../stitches.config";
2
+ import { forwardRef } from "react";
3
+ import { Spinner } from "./Spinner";
4
+
5
+ const ButtonStyled = styled("button", {
6
+ appearance: "none",
7
+ margin: 0,
8
+ padding: 0,
9
+ border: "none",
10
+ background: "none",
11
+ cursor: "pointer",
12
+ fontFamily: "inherit",
13
+ textAlign: "left",
14
+ textDecoration: "none",
15
+ textIndent: 0,
16
+ lineHeight: 1.25,
17
+ display: "inline-flex",
18
+ justifyContent: "center",
19
+ alignItems: "center",
20
+ gap: "$2",
21
+ position: "relative",
22
+ fontWeight: "$medium",
23
+ borderRadius: "$sm",
24
+ whiteSpace: "nowrap",
25
+
26
+ transition: "background 0.2s ease-in-out",
27
+
28
+ "&:focus, &:focus-visible": {
29
+ outline: "none",
30
+ },
31
+
32
+ "&:focus-visible": {
33
+ boxShadow: "0 0 0 2px white, 0 0 0 4px $colors$focusRing",
34
+ },
35
+
36
+ "&:disabled": {
37
+ cursor: "not-allowed",
38
+ },
39
+
40
+ variants: {
41
+ color: {
42
+ primary: {
43
+ $$solid: "$colors$blue600",
44
+ $$solidHover: "$colors$blue700",
45
+
46
+ $$outline: "$colors$blue600",
47
+ $$outlineHover: "$colors$blue100",
48
+ $$outlineText: "$colors$blue600",
49
+
50
+ $$disabled: "$colors$blue200",
51
+ },
52
+ secondary: {
53
+ $$solid: "$colors$gray600",
54
+ $$solidHover: "$colors$gray700",
55
+
56
+ $$outline: "$colors$gray400",
57
+ $$outlineHover: "$colors$gray100",
58
+ $$outlineText: "$colors$gray600",
59
+
60
+ $$disabled: "$colors$gray200",
61
+ },
62
+ success: {
63
+ $$solid: "$colors$green600",
64
+ $$solidHover: "$colors$green700",
65
+
66
+ $$outline: "$colors$green600",
67
+ $$outlineHover: "$colors$green100",
68
+ $$outlineText: "$colors$green600",
69
+
70
+ $$disabled: "$colors$green200",
71
+ },
72
+ danger: {
73
+ $$solid: "$colors$red600",
74
+ $$solidHover: "$colors$red700",
75
+
76
+ $$outline: "$colors$red600",
77
+ $$outlineHover: "$colors$red100",
78
+ $$outlineText: "$colors$red600",
79
+
80
+ $$disabled: "$colors$red200",
81
+ },
82
+ warning: {
83
+ $$solid: "$colors$yellow600",
84
+ $$solidHover: "$colors$yellow700",
85
+
86
+ $$outline: "$colors$yellow400",
87
+ $$outlineHover: "$colors$yellow50",
88
+ $$outlineText: "$colors$yellow600",
89
+
90
+ $$disabled: "$colors$yellow100",
91
+ },
92
+ },
93
+ size: {
94
+ md: {
95
+ fontSize: "$sm",
96
+ padding: "$2 $4",
97
+ height: "2.25rem",
98
+ },
99
+ lg: {
100
+ fontSize: "$md",
101
+ padding: "$3 $6",
102
+ height: "2.75rem",
103
+ },
104
+ },
105
+ variant: {
106
+ primary: {
107
+ background: "$$solid",
108
+ color: "white",
109
+ "&:hover:enabled": {
110
+ backgroundColor: "$$solidHover",
111
+ },
112
+ "&:disabled": {
113
+ backgroundColor: "$$disabled",
114
+ },
115
+ },
116
+ outline: {
117
+ boxShadow: "inset 0 0 0 1px $$outline",
118
+ color: "$$outlineText",
119
+ "&:hover:enabled": {
120
+ backgroundColor: "$$outlineHover",
121
+ },
122
+ "&:disabled": {
123
+ boxShadow: "inset 0 0 0 1px $$disabled",
124
+ color: "$$disabled",
125
+ },
126
+ },
127
+ transparent: {
128
+ backgroundColor: "transparent",
129
+ color: "$$outlineText",
130
+ "&:hover:enabled": {
131
+ backgroundColor: "$$outlineHover",
132
+ },
133
+ "&:disabled": {
134
+ color: "$$disabled",
135
+ },
136
+ },
137
+ },
138
+ },
139
+
140
+ defaultVariants: {
141
+ variant: "outline",
142
+ color: "secondary",
143
+ size: "md",
144
+ },
145
+ });
146
+
147
+ type ButtonProps = React.ComponentProps<typeof ButtonStyled> & {
148
+ as?: React.ElementType;
149
+ isLoading?: boolean;
150
+ };
151
+
152
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
153
+ ({ children, disabled, isLoading, variant, color, ...props }, ref) => {
154
+
155
+ if (!color && variant === "primary") {
156
+ color = "primary";
157
+ }
158
+
159
+ return (
160
+ <ButtonStyled
161
+ ref={ref}
162
+ type="button"
163
+ disabled={disabled || isLoading}
164
+ variant={variant}
165
+ color={color}
166
+ {...props}
167
+ >
168
+ {children}
169
+ {isLoading && <Spinner color="inherit" />}
170
+ </ButtonStyled>
171
+ );
172
+ },
173
+ );
@@ -0,0 +1,102 @@
1
+ import { forwardRef } from "react";
2
+ import { keyframes, styled } from "../stitches.config";
3
+
4
+ const spinnerKeyframes = keyframes({
5
+ "0%": {
6
+ transform: "rotate(0)",
7
+ },
8
+ "100%": {
9
+ transform: "rotate(360deg)",
10
+ },
11
+ });
12
+
13
+ const spinnerCircleKeyframes = keyframes({
14
+ "0%": {
15
+ strokeDashoffset: 600,
16
+ },
17
+ "100%": {
18
+ strokeDashoffset: 0,
19
+ },
20
+ });
21
+
22
+ const Svg = styled("svg", {
23
+ animation: `${spinnerKeyframes} 2s linear infinite`,
24
+ });
25
+
26
+ const Circle = styled("circle", {
27
+ animation: `${spinnerCircleKeyframes} 1.6s cubic-bezier(0.4, 0.15, 0.6, 0.85) infinite`,
28
+ fill: "transparent",
29
+ stroke: "currentColor",
30
+ strokeDasharray: 300,
31
+ strokeDashoffset: 600,
32
+ strokeLinecap: "round",
33
+ strokeMiterlimit: 10,
34
+ strokeWidth: 12,
35
+ });
36
+
37
+ const SpinnerStyled = styled("div", {
38
+ lineHeight: 0,
39
+ flexShrink: 0,
40
+
41
+ variants: {
42
+ size: {
43
+ xs: {
44
+ width: "1rem",
45
+ height: "1rem",
46
+ },
47
+ sm: {
48
+ width: "1.25rem",
49
+ height: "1.25rem",
50
+ },
51
+ md: {
52
+ width: "1.75rem",
53
+ height: "1.75rem",
54
+ },
55
+ lg: {
56
+ width: "2.25rem",
57
+ height: "2.25rem",
58
+ },
59
+ },
60
+ color: {
61
+ light: {
62
+ color: "$gray200",
63
+ },
64
+ dark: {
65
+ color: "$gray800",
66
+ },
67
+ inherit: {
68
+ color: "inherit",
69
+ },
70
+ },
71
+ },
72
+
73
+ defaultVariants: {
74
+ size: "sm",
75
+ color: "dark",
76
+ },
77
+ });
78
+
79
+ type SpinnerProps = React.ComponentProps<typeof SpinnerStyled>;
80
+
81
+ export const Spinner = forwardRef<HTMLDivElement, SpinnerProps>(
82
+ (props, ref) => {
83
+ return (
84
+ <SpinnerStyled
85
+ ref={ref}
86
+ {...props}
87
+ >
88
+ <Svg
89
+ x="0px"
90
+ y="0px"
91
+ viewBox="0 0 150 150"
92
+ >
93
+ <Circle
94
+ cx="75"
95
+ cy="75"
96
+ r="60"
97
+ />
98
+ </Svg>
99
+ </SpinnerStyled>
100
+ );
101
+ },
102
+ );
@@ -0,0 +1,144 @@
1
+ import { createStitches } from "@stitches/react";
2
+
3
+ let zIndex = 9999;
4
+ const createLayerBelow = () => {
5
+ zIndex--;
6
+ return zIndex;
7
+ };
8
+
9
+ // Colors from palette: https://accessiblepalette.com/?lightness=98.2,93.9,85,76.2,67,57.8,48,39,31.8,21&A52422=0,0&d6751d=0,0&E4B420=0,0&2e7641=0,0&228997=0,0&6D597A=0,0&6c8184=0,0
10
+
11
+ // 900 has enough contrast on 300
12
+ // 700 has enough contrast on 200
13
+ // 500+ has enough contrast with white
14
+ // 300- has enough contrast with black (or gray900)
15
+
16
+ export const { styled, css, keyframes, globalCss } = createStitches({
17
+ theme: {
18
+ colors: {
19
+ gray50: "#F9FAFA",
20
+ gray100: "#EBEEEE",
21
+ gray200: "#CFD6D7",
22
+ gray300: "#B3BEC0",
23
+ gray400: "#97A6A8",
24
+ gray500: "#7C8E91",
25
+ gray600: "#627578",
26
+ gray700: "#4F5F61",
27
+ gray800: "#414D4F",
28
+ gray900: "#2C3435",
29
+
30
+ blue50: "#F7FBFB",
31
+ blue100: "#E3F0F2",
32
+ blue200: "#BADADF",
33
+ blue300: "#92C5CC",
34
+ blue400: "#67AEB8",
35
+ blue500: "#3C97A3",
36
+ blue600: "#1F7D8A",
37
+ blue700: "#19656F",
38
+ blue800: "#14525B",
39
+ blue900: "#0E383E",
40
+
41
+ yellow50: "#FDFAEF",
42
+ yellow100: "#F9EDCA",
43
+ yellow200: "#EFD27A",
44
+ yellow300: "#E5B626",
45
+ yellow400: "#C89E1C",
46
+ yellow500: "#AA8618",
47
+ yellow600: "#8C6E14",
48
+ yellow700: "#715910",
49
+ yellow800: "#5C490D",
50
+ yellow900: "#3E3109",
51
+
52
+ orange500: "#D1721C",
53
+
54
+ red50: "#FDF9F9",
55
+ red100: "#F7EBEB",
56
+ red200: "#EBCECD",
57
+ red300: "#DFB1B0",
58
+ red400: "#D39392",
59
+ red500: "#C67473",
60
+ red600: "#B85250",
61
+ red700: "#A92F2D",
62
+ red800: "#901F1E",
63
+ red900: "#631614",
64
+
65
+ green50: "#F8FAF9",
66
+ green100: "#E7F0EA",
67
+ green200: "#C5D9CB",
68
+ green300: "#A4C4AD",
69
+ green400: "#82AD8D",
70
+ green500: "#60976F",
71
+ green600: "#3C7F4E",
72
+ green700: "#296839",
73
+ green800: "#21552F",
74
+ green900: "#163920",
75
+
76
+ // Primary
77
+ primaryTextOnLightBg: "#194b58",
78
+ primaryBg: "$blue600",
79
+ primaryBgHover: "$blue700",
80
+ primaryTextOnWhite: "$blue600",
81
+
82
+ bodyGray: "$gray100",
83
+ hoverDarker: "hsla(214deg, 25%, 21%, 0.06)",
84
+ borderDarker: "hsla(214deg, 25%, 21%, 0.1)",
85
+ selectedDarker: "hsla(214deg, 25%, 21%, 0.06)",
86
+ selectedOnBodyGray: "hsl(214deg, 35%, 80%)",
87
+ darkGrayBg: "#1f2937",
88
+ border: "hsl(214deg, 25%, 80%)",
89
+ text: "#1f2937",
90
+ secondaryText: "$gray500",
91
+ focusRing: "hsla(214deg, 15%, 10%, 0.6)",
92
+ },
93
+ fontSizes: {
94
+ xs: "0.75rem", // 12px
95
+ sm: "0.875rem", // 14px
96
+ md: "1rem", // 16px
97
+ lg: "1.125rem", // 18px
98
+ xl: "1.25rem", // 20px
99
+ "2xl": "1.5rem", // 24px
100
+ "3xl": "1.875rem", // 30px
101
+ },
102
+ fontWeights: {
103
+ normal: "var(--ui-font-weight-normal)",
104
+ medium: "var(--ui-font-weight-semibold)",
105
+ bold: "var(--ui-font-weight-bold)",
106
+ },
107
+ space: {
108
+ 1: "0.25rem",
109
+ 2: "0.5rem",
110
+ 3: "0.75rem",
111
+ 4: "1rem",
112
+ 6: "1.5rem",
113
+ 8: "2rem",
114
+ },
115
+ shadows: {
116
+ xs: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
117
+ sm: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)",
118
+ md: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
119
+ lg: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
120
+ overlayCard:
121
+ "0 5px 50px 0px rgb(0 0 0 / 0.15), 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
122
+ },
123
+ radii: {
124
+ xs: "0.125rem",
125
+ sm: "0.25rem",
126
+ md: "0.5rem",
127
+ mdmd: "calc(0.5rem - 0.125rem)",
128
+ full: "9999px",
129
+ },
130
+ zIndices: {
131
+ /**
132
+ * By using createLayerBelow() we can order the list of layers.
133
+ * Layers higher up will be on top of layers lower down.
134
+ */
135
+ toast: createLayerBelow(),
136
+ overlayCard: createLayerBelow(),
137
+ modal: createLayerBelow(),
138
+ },
139
+ },
140
+ media: {
141
+ lg: "(min-width: 1200px)",
142
+ print: "print",
143
+ },
144
+ });
@@ -0,0 +1,11 @@
1
+ :root {
2
+ --ui-font-family: system-ui, sans-serif;
3
+ --ui-font-weight-normal: 400;
4
+ --ui-font-weight-semibold: 500;
5
+ --ui-font-weight-bold: 700;
6
+ }
7
+
8
+ body {
9
+ font-family: var(--ui-font-family);
10
+ font-weight: var(--ui-font-weight-normal);
11
+ }
@@ -0,0 +1,5 @@
1
+ export * from './stitches.config';
2
+
3
+ export * from './components/Button';
4
+ export * from './components/Spinner';
5
+ export * from './components/Alert';
package/vite.config.ts CHANGED
@@ -5,6 +5,7 @@ import dts from "vite-plugin-dts";
5
5
  // https://vitejs.dev/config/
6
6
  export default defineConfig({
7
7
  build: {
8
+ cssCodeSplit: true,
8
9
  lib: {
9
10
  entry: [
10
11
  "src/lib/index.ts",
@@ -13,6 +14,8 @@ export default defineConfig({
13
14
  "src/lib/icons/icons.tsx",
14
15
  "src/lib/colors/colors.ts",
15
16
  "src/lib/rich-text/rich-text.ts",
17
+ "src/lib/ui/ui.ts",
18
+ "src/lib/ui/ui.css",
16
19
  ],
17
20
  name: "fe-lib",
18
21
  formats: ["es"],