@digitalservicebund/ris-ui 0.0.1

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/README.md ADDED
@@ -0,0 +1,150 @@
1
+ # RIS UI
2
+
3
+ **Component library for NeuRIS** | 👀 [Demo](https://digitalservicebund.github.io/ris-ui) | 🤖 [PrimeVue Docs](https://primevue.org)
4
+
5
+ ## Installation
6
+
7
+ RUI UI contains two things:
8
+
9
+ - a theme for [Vue 3](https://vuejs.org) components from [PrimeVue 4](https://primevue.org);
10
+ - a preset and plugin for [Tailwind](https://tailwindcss.com) that sets some global styling and exposes the design tokens used by the theme, so you can build custom UI that looks consistent with the components.
11
+
12
+ Vue and PrimeVue are required for RIS UI to work (you'll see a warning about missing peer dependencies if you're trying to use RIS UI without them). Tailwind is optional. To get started, install:
13
+
14
+ ```sh
15
+ # Vue and PrimeVue if you haven't installed them already. Tailwind is optional.
16
+ npm install vue primevue tailwindcss
17
+
18
+ # RIS UI
19
+ npm install @digitalservicebund/ris-ui
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ Import and apply the RIS UI theme and styling where you set up your application (typically `main.ts`):
25
+
26
+ ```diff
27
+ // main.ts
28
+ import { createApp } from "vue";
29
+ import PrimeVue from "primevue/config";
30
+ + import { RisUiTheme } from "@digitalservicebund/ris-ui/primevue";
31
+ + import "@digitalservicebund/ris-ui/primevue/style.css";
32
+
33
+ const app = createApp().use(PrimeVue, {
34
+ + unstyled: true,
35
+ + pt: RisUiTheme,
36
+ })
37
+ ```
38
+
39
+ If you want, also install the Tailwind preset (for colors, spacings, etc.) and plugin (for typography classes, etc.):
40
+
41
+ ```diff
42
+ // tailwind.config.js
43
+ + import { RisUiPreset, RisUiPlugin } from "@digitalservicebund/ris-ui/tailwind";
44
+
45
+ export default {
46
+ + presets: [RisUiPreset],
47
+ + plugins: [RisUiPlugin],
48
+
49
+ // your other configuration
50
+ };
51
+ ```
52
+
53
+ ## Development
54
+
55
+ If you want to make changes to RIS UI, you'll need the current [Node.js LTS](https://nodejs.org/en/download/package-manager) as well as NPM installed on your machine.
56
+
57
+ To get started, first clone this repository:
58
+
59
+ ```sh
60
+ git clone https://github.com/digitalservicebund/ris-ui.git
61
+ ```
62
+
63
+ Then install dependencies:
64
+
65
+ ```sh
66
+ npm install
67
+ ```
68
+
69
+ You can now run a local preview to see any changes you make to the code:
70
+
71
+ ```sh
72
+ npm run storybook
73
+ ```
74
+
75
+ Check out [package.json](./package.json) for additional scripts.
76
+
77
+ ### Repository contents
78
+
79
+ RIS UI uses the following tools:
80
+
81
+ - [Storybook](https://storybook.js.org/), a playground for previewing components and styling
82
+ - [Tailwind](https://tailwindcss.com/) for styling
83
+ - [Vite](https://vitejs.dev/) as our dev server and bundler
84
+ - [Unplugin Icons](https://github.com/unplugin/unplugin-icons) for providing SVG icons as components
85
+ - [TypeScript](https://www.typescriptlang.org/)
86
+ - [ESLint](https://eslint.org/) and [Prettier](https://prettier.io/) for code consistency
87
+
88
+ You can find more in [package.json](./package.json), but the above are the ones you'll work with the most.
89
+
90
+ In terms of files and folders, you'll find:
91
+
92
+ | Folder | Contents |
93
+ | -------------- | ----------------------------------------- |
94
+ | (root) | General docs and configuration |
95
+ | `.github/` | GitHub Actions configuration |
96
+ | `.storybook/` | Storybook setup |
97
+ | `src/primevue` | The RIS UI preset for PrimeVue |
98
+ | `src/tailwind` | The RIS UI preset and plugin for Tailwind |
99
+ | `src/lib` | Internal tools and helpers |
100
+
101
+ ### Tailwind IntelliSense
102
+
103
+ If you're using VS Code with the [official Tailwind extension](https://tailwindcss.com/docs/editor-setup), you can get autocompletions and more by adding this to your VS Code settings:
104
+
105
+ ```jsonc
106
+ {
107
+ // other settings
108
+ "tailwindCSS.experimental.classRegex": ["tw`([^`]*)`"],
109
+ }
110
+ ```
111
+
112
+ This will detect Tailwind CSS classes in template strings tagged with `tw` such as:
113
+
114
+ ```ts
115
+ import { tw } from "@/lib/tags";
116
+
117
+ const classes = tw`bg-blue-200 px-16`;
118
+ ```
119
+
120
+ See [tags.ts](./src/lib/tags.ts) for more information.
121
+
122
+ ### Committing
123
+
124
+ Before making your first commit, you'll need some additional prerequisites installed. These help us with code consistency and quality:
125
+
126
+ - [GitHub CLI](https://cli.github.com/): Used for checking the pipeline status before pushing
127
+ - [jq](https://jqlang.github.io/jq/): Used by our license check, which ensures all our dependencies use [allowed licenses](./allowed-licenses.json) only
128
+ - [Lefthook](https://github.com/evilmartians/lefthook): Runs Git commit hooks
129
+ - [Talisman](https://github.com/thoughtworks/talisman): Validates you're not accidentially committing secrets
130
+
131
+ Once they're installed, run:
132
+
133
+ ```sh
134
+ # In ./ris-ui
135
+ lefthook install
136
+ ```
137
+
138
+ When you make a commit now, Lefthook will ensure your changes and commit message adhere to our coding guidelines:
139
+
140
+ - Code is formatted with Prettier
141
+ - ESLint passes without warnings
142
+ - The commit message follows the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. If you're making changes to a component, please use the component name as the scope (multiple scopes are allowed).
143
+
144
+ ### Making a release
145
+
146
+ > 🚜 Under construction
147
+
148
+ ## Contributing
149
+
150
+ See [CONTRIBUTING.md](./CONTRIBUTING.md).
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Tagged template string for HTML. The tag itself doesn't do anything, but
3
+ * using it will allow your editor to provide HTML-features for template
4
+ * strings in scripts, e.g. stories:
5
+ *
6
+ * ```ts
7
+ * const template = html`<div>Hello world</div>`
8
+ * ```
9
+ */
10
+ export declare const html: (strings: TemplateStringsArray, ...expressions: unknown[]) => string;
11
+ /**
12
+ * Tagges template string for Tailwind classes. The tag itself doesn't do
13
+ * anything, but using it will allow your editor to provide Tailwind
14
+ * Intellisense for template strings in scripts, as well as automatic class
15
+ * sorting via Prettier.
16
+ *
17
+ * ```ts
18
+ * const classes = tw`px-16 bg-blue-200`
19
+ * ```
20
+ */
21
+ export declare const tw: (strings: TemplateStringsArray, ...expressions: unknown[]) => string;
@@ -0,0 +1,3 @@
1
+ import { ButtonPassThroughOptions } from "primevue/button";
2
+ declare const button: ButtonPassThroughOptions;
3
+ export default button;
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c={root:({props:e,context:o,instance:l})=>{let t,r,n,a,s,u;return l.hasIcon&&e.size==="large"&&e.label&&(e.iconPos==="left"?t="pl-20 pr-24 gap-8":e.iconPos==="right"&&(t="pl-24 pr-20 gap-8")),l.hasIcon&&(!e.size||e.size==="small")&&e.label&&(e.iconPos==="left"?t="pl-12 pr-16 gap-4":e.iconPos==="right"&&(t="pl-16 pr-12 gap-4")),l.hasIcon&&!e.label&&(t="p-0 gap-0"),e.size==="large"?r=e.label?"py-20 px-24 text-[1.125rem] min-h-64":"w-64 h-64":r=e.label?"py-8 px-16 text-base min-h-48":"w-48 h-48",e.severity==="primary"&&(o.disabled?n="bg-gray-400 cursor-not-allowed text-gray-600 border-transparent":n="bg-blue-800 border-transparent text-white hover:bg-blue-700 active:bg-blue-500 active:text-blue-800 focus:outline-none focus:ring-blue-800 focus:ring-4 focus:ring-offset-4"),e.severity==="secondary"&&(o.disabled?a="bg-white cursor-not-allowed text-blue-800 text-opacity-50 border-blue-800 border-opacity-50":a="bg-white text-blue-800 border-solid border-blue-800 hover:bg-gray-200 active:bg-white active:text-blue-800 active:border-transparent focus:outline-none focus:ring-blue-800 focus:ring-4 focus:ring-offset-2 focus:bg-gray-200"),e.severity==="ghost"&&(o.disabled?s="cursor-not-allowed text-gray-800 text-opacity-50 border-transparent":s="bg-transparent text-blue-800 border-transparent hover:bg-white hover:border-gray-500 hover:border-2 hover:border-solid active:bg-white active:border-transparent focus:outline-none focus:ring-blue-800 focus:ring-4 focus:ring-offset-4 focus:bg-white focus:border-gray-500 focus:border-2 focus:border-solid"),l.hasIcon&&(e.iconPos==="left"?u="flex-row":e.iconPos==="right"&&(u="flex-row-reverse")),{class:["inline-flex","items-center","justify-center","font-bold","text-center","max-w-full","leading-24","rounded-none","box-border","border","border-2",!o.disabled&&"focus:outline-none focus:ring-4 focus:ring-offset-4",!e.size&&"py-8 px-16 text-base min-h-48",t,r,n,a,s,u]}},label:({props:e})=>({class:[{underline:e.severity==="ghost"},{"sr-only":!e.label}]})},g=(e,...o)=>{let l=e[0];for(let t=1,r=e.length;t<r;t++)l+=o[t-1],l+=e[t];return l},i=g,f={root:{class:i`has-[input:read-only]:curser-not-allowed inline-flex items-center gap-4 border-2 border-blue-800 bg-white px-16 py-0 outline-4 -outline-offset-4 outline-blue-800 has-[[aria-invalid]]:border-red-800 has-[input:disabled]:border-blue-500 has-[input:read-only]:border-blue-300 has-[[aria-invalid]]:bg-red-200 has-[input:disabled]:bg-white has-[input:read-only]:bg-blue-300 has-[[data-size=large]]:px-24 has-[input:disabled]:text-blue-500 has-[input:disabled]:outline-none has-[:focus]:outline has-[:hover]:outline has-[[aria-invalid]]:outline-red-800`}},h={root:{class:i`m-0 p-0`}},y={root:({props:e,parent:o})=>{const l=i`border-2 border-blue-800 bg-white outline-4 -outline-offset-4 outline-blue-800 placeholder:text-gray-900 read-only:cursor-not-allowed read-only:border-blue-300 read-only:bg-blue-300 hover:outline focus:outline disabled:border-blue-500 disabled:bg-white disabled:text-blue-500 disabled:outline-none aria-[invalid]:border-red-800 aria-[invalid]:bg-red-200 aria-[invalid]:outline-red-800 aria-[invalid]:disabled:outline-none`,t=i`[&[type=password]:not(:placeholder-shown)]:text-[28px] [&[type=password]:not(:placeholder-shown)]:tracking-[4px] [&[type=password]]:w-full`,r=o.instance.$name==="InputGroup",n=i`bg-transparent placeholder:text-gray-900 focus:outline-none`,a=i`w-full`,s=i`ris-body2-regular h-48 px-16 py-4`,u=i`ris-body1-regular h-64 px-24 py-4`,d=i`ris-body2-regular h-[44px] p-0`,b=i`ris-body1-regular h-[60px] p-0`;return{class:{[l]:!r,[n]:r,[a]:!!e.fluid,[t]:!0,[s]:(!e.size||e.size==="small")&&!r,[d]:(!e.size||e.size==="small")&&r,[u]:e.size==="large"&&!r,[b]:e.size==="large"&&r},"data-size":e.size??"small"}}},x={},v={button:c,inputText:y,inputGroup:f,inputGroupAddon:h,password:x};exports.RisUi=v;
@@ -0,0 +1,8 @@
1
+ import "./global.css";
2
+ export declare const RisUi: {
3
+ button: import("primevue/button").ButtonPassThroughOptions<any>;
4
+ inputText: import("primevue/inputtext").InputTextPassThroughOptions<any>;
5
+ inputGroup: import("primevue/inputgroup").InputGroupPassThroughOptions;
6
+ inputGroupAddon: import("primevue/inputgroupaddon").InputGroupAddonPassThroughOptions;
7
+ password: import("primevue/password").PasswordPassThroughOptions;
8
+ };
@@ -0,0 +1,75 @@
1
+ const c = {
2
+ root: ({ props: e, context: o, instance: l }) => {
3
+ let r, t, n, a, s, u;
4
+ return l.hasIcon && e.size === "large" && e.label && (e.iconPos === "left" ? r = "pl-20 pr-24 gap-8" : e.iconPos === "right" && (r = "pl-24 pr-20 gap-8")), l.hasIcon && (!e.size || e.size === "small") && e.label && (e.iconPos === "left" ? r = "pl-12 pr-16 gap-4" : e.iconPos === "right" && (r = "pl-16 pr-12 gap-4")), l.hasIcon && !e.label && (r = "p-0 gap-0"), e.size === "large" ? t = e.label ? "py-20 px-24 text-[1.125rem] min-h-64" : "w-64 h-64" : t = e.label ? "py-8 px-16 text-base min-h-48" : "w-48 h-48", e.severity === "primary" && (o.disabled ? n = "bg-gray-400 cursor-not-allowed text-gray-600 border-transparent" : n = "bg-blue-800 border-transparent text-white hover:bg-blue-700 active:bg-blue-500 active:text-blue-800 focus:outline-none focus:ring-blue-800 focus:ring-4 focus:ring-offset-4"), e.severity === "secondary" && (o.disabled ? a = "bg-white cursor-not-allowed text-blue-800 text-opacity-50 border-blue-800 border-opacity-50" : a = "bg-white text-blue-800 border-solid border-blue-800 hover:bg-gray-200 active:bg-white active:text-blue-800 active:border-transparent focus:outline-none focus:ring-blue-800 focus:ring-4 focus:ring-offset-2 focus:bg-gray-200"), e.severity === "ghost" && (o.disabled ? s = "cursor-not-allowed text-gray-800 text-opacity-50 border-transparent" : s = "bg-transparent text-blue-800 border-transparent hover:bg-white hover:border-gray-500 hover:border-2 hover:border-solid active:bg-white active:border-transparent focus:outline-none focus:ring-blue-800 focus:ring-4 focus:ring-offset-4 focus:bg-white focus:border-gray-500 focus:border-2 focus:border-solid"), l.hasIcon && (e.iconPos === "left" ? u = "flex-row" : e.iconPos === "right" && (u = "flex-row-reverse")), {
5
+ class: [
6
+ "inline-flex",
7
+ "items-center",
8
+ "justify-center",
9
+ "font-bold",
10
+ "text-center",
11
+ "max-w-full",
12
+ "leading-24",
13
+ "rounded-none",
14
+ "box-border",
15
+ "border",
16
+ "border-2",
17
+ !o.disabled && "focus:outline-none focus:ring-4 focus:ring-offset-4",
18
+ !e.size && "py-8 px-16 text-base min-h-48",
19
+ r,
20
+ t,
21
+ n,
22
+ a,
23
+ s,
24
+ u
25
+ ]
26
+ };
27
+ },
28
+ label: ({ props: e }) => ({
29
+ class: [
30
+ { underline: e.severity === "ghost" },
31
+ { "sr-only": !e.label }
32
+ ]
33
+ })
34
+ }, g = (e, ...o) => {
35
+ let l = e[0];
36
+ for (let r = 1, t = e.length; r < t; r++)
37
+ l += o[r - 1], l += e[r];
38
+ return l;
39
+ }, i = g, f = {
40
+ root: {
41
+ class: i`has-[input:read-only]:curser-not-allowed inline-flex items-center gap-4 border-2 border-blue-800 bg-white px-16 py-0 outline-4 -outline-offset-4 outline-blue-800 has-[[aria-invalid]]:border-red-800 has-[input:disabled]:border-blue-500 has-[input:read-only]:border-blue-300 has-[[aria-invalid]]:bg-red-200 has-[input:disabled]:bg-white has-[input:read-only]:bg-blue-300 has-[[data-size=large]]:px-24 has-[input:disabled]:text-blue-500 has-[input:disabled]:outline-none has-[:focus]:outline has-[:hover]:outline has-[[aria-invalid]]:outline-red-800`
42
+ }
43
+ }, h = {
44
+ root: {
45
+ class: i`m-0 p-0`
46
+ }
47
+ }, y = {
48
+ root: ({ props: e, parent: o }) => {
49
+ const l = i`border-2 border-blue-800 bg-white outline-4 -outline-offset-4 outline-blue-800 placeholder:text-gray-900 read-only:cursor-not-allowed read-only:border-blue-300 read-only:bg-blue-300 hover:outline focus:outline disabled:border-blue-500 disabled:bg-white disabled:text-blue-500 disabled:outline-none aria-[invalid]:border-red-800 aria-[invalid]:bg-red-200 aria-[invalid]:outline-red-800 aria-[invalid]:disabled:outline-none`, r = i`[&[type=password]:not(:placeholder-shown)]:text-[28px] [&[type=password]:not(:placeholder-shown)]:tracking-[4px] [&[type=password]]:w-full`, t = o.instance.$name === "InputGroup", n = i`bg-transparent placeholder:text-gray-900 focus:outline-none`, a = i`w-full`, s = i`ris-body2-regular h-48 px-16 py-4`, u = i`ris-body1-regular h-64 px-24 py-4`, d = i`ris-body2-regular h-[44px] p-0`, b = i`ris-body1-regular h-[60px] p-0`;
50
+ return {
51
+ class: {
52
+ [l]: !t,
53
+ [n]: t,
54
+ [a]: !!e.fluid,
55
+ [r]: !0,
56
+ [s]: (!e.size || e.size === "small") && !t,
57
+ [d]: (!e.size || e.size === "small") && t,
58
+ [u]: e.size === "large" && !t,
59
+ [b]: e.size === "large" && t
60
+ },
61
+ "data-size": e.size ?? "small"
62
+ };
63
+ }
64
+ }, x = {
65
+ // All styling moved to inputText.ts
66
+ }, w = {
67
+ button: c,
68
+ inputText: y,
69
+ inputGroup: f,
70
+ inputGroupAddon: h,
71
+ password: x
72
+ };
73
+ export {
74
+ w as RisUi
75
+ };
@@ -0,0 +1,3 @@
1
+ import { InputGroupPassThroughOptions } from "primevue/inputgroup";
2
+ declare const inputGroup: InputGroupPassThroughOptions;
3
+ export default inputGroup;
@@ -0,0 +1,3 @@
1
+ import { InputGroupAddonPassThroughOptions } from "primevue/inputgroupaddon";
2
+ declare const inputGroupAddon: InputGroupAddonPassThroughOptions;
3
+ export default inputGroupAddon;
@@ -0,0 +1,4 @@
1
+ import { InputTextPassThroughOptions } from "primevue/inputtext";
2
+ import "./inputText.css";
3
+ declare const inputText: InputTextPassThroughOptions;
4
+ export default inputText;
@@ -0,0 +1,3 @@
1
+ import { PasswordPassThroughOptions } from "primevue/password";
2
+ declare const password: PasswordPassThroughOptions;
3
+ export default password;