@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/LICENSE.md +674 -0
- package/README.md +150 -0
- package/dist/lib/tags.d.ts +21 -0
- package/dist/primevue/button/button.d.ts +3 -0
- package/dist/primevue/index.cjs +1 -0
- package/dist/primevue/index.d.ts +8 -0
- package/dist/primevue/index.js +75 -0
- package/dist/primevue/inputGroup/inputGroup.d.ts +3 -0
- package/dist/primevue/inputGroup/inputGroupAddon.d.ts +3 -0
- package/dist/primevue/inputText/inputText.d.ts +4 -0
- package/dist/primevue/password/password.d.ts +3 -0
- package/dist/style.css +1 -0
- package/dist/tailwind/index.cjs +1 -0
- package/dist/tailwind/index.d.ts +6 -0
- package/dist/tailwind/index.js +349 -0
- package/package.json +80 -0
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 @@
|
|
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
|
+
};
|