superdesk-ui-framework 6.1.3 → 6.1.4

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.
Files changed (55) hide show
  1. package/.github/CODEOWNERS +1 -1
  2. package/.github/workflows/publish-to-npm.yml +41 -32
  3. package/.prettierignore +2 -1
  4. package/CLAUDE.md +85 -0
  5. package/app/styles/_avatar.scss +0 -3
  6. package/app/styles/_design-tokens.scss +4 -5
  7. package/app/styles/_toggle-button.scss +3 -3
  8. package/app/styles/components/_list-item.scss +1 -0
  9. package/app/styles/components/_sd-photo-preview.scss +9 -7
  10. package/app/styles/design-tokens/_design-tokens-general.scss +50 -12
  11. package/app/styles/design-tokens/components/_checkbox-button.scss +14 -0
  12. package/app/styles/design-tokens/components/_checkbox.scss +13 -0
  13. package/app/styles/design-tokens/components/_components.scss +3 -0
  14. package/app/styles/design-tokens/primitives/_primitives.scss +2 -0
  15. package/app/styles/design-tokens/semantic/_semantics.scss +1 -0
  16. package/app/styles/form-elements/_checkbox.scss +105 -107
  17. package/app/styles/primereact/_pr-dropdown.scss +2 -2
  18. package/app-typescript/components/Button.stories.tsx +2 -1
  19. package/app-typescript/components/Lists/TableList.tsx +1 -1
  20. package/app-typescript/components/TreeSelect/TreeSelect.tsx +1 -1
  21. package/dist/components/BigIconFont.tsx +1 -1
  22. package/dist/components/IconFont.tsx +1 -1
  23. package/dist/examples.bundle.css +2 -2
  24. package/dist/examples.bundle.js +1 -1
  25. package/dist/examples.bundle.js.LICENSE.txt +30 -9
  26. package/dist/storybook/{components-Button-stories.d513b08d.iframe.bundle.js → components-Button-stories.d26accad.iframe.bundle.js} +1 -1
  27. package/dist/storybook/iframe.html +2 -2
  28. package/dist/storybook/main.2713e2b2.iframe.bundle.js +1 -0
  29. package/dist/storybook/manifests/components.html +1 -1
  30. package/dist/storybook/manifests/components.json +1 -1
  31. package/dist/storybook/project.json +1 -1
  32. package/dist/storybook/{runtime~main.4063e973.iframe.bundle.js → runtime~main.7d9dbba0.iframe.bundle.js} +1 -1
  33. package/dist/superdesk-ui.bundle.css +1 -1
  34. package/dist/superdesk-ui.bundle.js +1 -1
  35. package/dist/superdesk-ui.bundle.js.LICENSE.txt +23 -2
  36. package/package.json +3 -4
  37. package/react/components/Lists/TableList.d.ts +1 -1
  38. package/react/components/Lists/TableList.js +4 -4
  39. package/react/components/TreeSelect/TreeSelect.d.ts +1 -1
  40. package/react/components/TreeSelect/TreeSelect.js +4 -4
  41. package/storybook-static/{components-Button-stories.d513b08d.iframe.bundle.js → components-Button-stories.d26accad.iframe.bundle.js} +1 -1
  42. package/storybook-static/iframe.html +2 -2
  43. package/storybook-static/main.2713e2b2.iframe.bundle.js +1 -0
  44. package/storybook-static/manifests/components.html +1 -1
  45. package/storybook-static/manifests/components.json +1 -1
  46. package/storybook-static/project.json +1 -1
  47. package/storybook-static/{runtime~main.4063e973.iframe.bundle.js → runtime~main.7d9dbba0.iframe.bundle.js} +1 -1
  48. package/webpack.config.js +1 -0
  49. package/dist/storybook/main.6ba8c211.iframe.bundle.js +0 -1
  50. package/storybook-static/main.6ba8c211.iframe.bundle.js +0 -1
  51. /package/app/styles/{design-tokens → deprecate}/_new-colors.scss +0 -0
  52. /package/app/styles/design-tokens/{_component-tokens.scss → components/_drag-handle.scss} +0 -0
  53. /package/app/styles/design-tokens/{_brand-colors.scss → primitives/_brand-colors.scss} +0 -0
  54. /package/app/styles/design-tokens/{_primitives.scss → primitives/_colors.scss} +0 -0
  55. /package/app/styles/design-tokens/{_semantic-colors.scss → semantic/_semantic-colors.scss} +0 -0
@@ -1 +1 @@
1
- /app-typescript/ @eos87 @thecalcc
1
+ /app-typescript/ @eos87
@@ -1,64 +1,73 @@
1
1
  name: Publish to npm and Create Release
2
2
 
3
3
  on:
4
- push:
5
- branches:
6
- - 'v3'
7
- - 'v4'
8
- - 'v5'
9
- - 'v6*'
10
4
  workflow_dispatch:
11
5
  inputs:
12
- branch:
13
- description: 'Branch to publish from (leave empty to use current branch)'
14
- required: false
15
- type: string
16
- default: ''
6
+ bump:
7
+ description: 'Version bump before publishing (none = publish current package.json version)'
8
+ required: true
9
+ type: choice
10
+ default: 'none'
11
+ options:
12
+ - none
13
+ - patch
14
+ - minor
15
+ - major
17
16
 
18
17
  jobs:
19
18
  publish:
20
19
  runs-on: ubuntu-latest
21
20
  permissions:
22
21
  contents: write
22
+ id-token: write
23
23
  steps:
24
24
  - uses: actions/checkout@v6
25
25
  with:
26
- ref: ${{ github.event.inputs.branch || github.ref }}
27
26
  fetch-depth: 0
28
27
  - uses: actions/setup-node@v6
29
28
  with:
30
29
  node-version: '22'
31
30
  - run: npm ci
32
- - run: npm run lint
33
- - run: npm run build
34
- - uses: JS-DevTools/npm-publish@v4
35
- id: publish
36
- continue-on-error: true
37
- with:
38
- token: ${{ secrets.NPM_TOKEN }}
39
31
 
40
- - name: Check publish result
41
- if: steps.publish.outcome == 'failure'
32
+ - name: Bump version
33
+ if: inputs.bump != 'none'
42
34
  run: |
43
- echo "::notice::Package was not published. Version may already exist on npm."
44
- exit 0
35
+ git config user.name "github-actions[bot]"
36
+ git config user.email "github-actions[bot]@users.noreply.github.com"
37
+ npm version ${{ inputs.bump }} -m "Bump version to %s and release"
45
38
 
46
- - name: Get package version
47
- if: steps.publish.outputs.type != 'none' && steps.publish.outcome == 'success'
39
+ - name: Resolve target version
48
40
  id: package-version
49
41
  run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
50
42
 
51
- - name: Create Git tag
52
- if: steps.publish.outputs.type != 'none' && steps.publish.outcome == 'success'
43
+ - name: Ensure version is not already published
53
44
  run: |
54
- git config user.name "github-actions[bot]"
55
- git config user.email "github-actions[bot]@users.noreply.github.com"
56
- git tag -a "v${{ steps.package-version.outputs.version }}" -m "Release v${{ steps.package-version.outputs.version }}"
45
+ VERSION="${{ steps.package-version.outputs.version }}"
46
+ if [ -n "$(npm view superdesk-ui-framework@"$VERSION" version 2>/dev/null)" ]; then
47
+ echo "::error::superdesk-ui-framework@$VERSION is already published to npm. Choose a version bump (patch/minor/major) and re-run."
48
+ exit 1
49
+ fi
50
+ echo "::notice::superdesk-ui-framework@$VERSION is available; proceeding to publish."
51
+
52
+ - run: npm run lint
53
+ - run: npm run build
54
+
55
+ - name: Upgrade npm for OIDC trusted publishing
56
+ run: npm install -g npm@11
57
+
58
+ - uses: JS-DevTools/npm-publish@v4
59
+ id: publish
60
+ with:
61
+ provenance: true
62
+
63
+ - name: Push version bump and tag
64
+ if: inputs.bump != 'none'
65
+ run: |
66
+ git push origin "HEAD:${{ github.ref_name }}"
57
67
  git push origin "v${{ steps.package-version.outputs.version }}"
58
68
 
59
69
  - name: Create GitHub Release
60
- if: steps.publish.outputs.type != 'none' && steps.publish.outcome == 'success'
61
- uses: softprops/action-gh-release@v1
70
+ uses: softprops/action-gh-release@v3
62
71
  with:
63
72
  tag_name: v${{ steps.package-version.outputs.version }}
64
73
  name: v${{ steps.package-version.outputs.version }}
package/.prettierignore CHANGED
@@ -2,4 +2,5 @@
2
2
  **/*.scss
3
3
  app
4
4
  package.json
5
- package-lock.json
5
+ package-lock.json
6
+ CLAUDE.md
package/CLAUDE.md ADDED
@@ -0,0 +1,85 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Commands
6
+
7
+ ```bash
8
+ npm start # Dev server at localhost:9100
9
+ npm run storybook # Storybook dev at localhost:6006
10
+ npm run unit-test # Run Mocha tests
11
+ npm run lint # Full lint suite (tsc + prettier + eslint + tslint + unit-test)
12
+ npm run lint-fix # Auto-fix TSLint issues
13
+ npm run format-code # Format with Prettier (--write)
14
+ npm run build # Full production build (tsc → webpack → storybook → copy)
15
+ npm run watch # Watch mode: webpack + tsc
16
+ ```
17
+
18
+ There is no command to run a single test file directly. Tests are all run via `npm run unit-test`.
19
+
20
+ ## Architecture
21
+
22
+ This is a React component library (with legacy Angular 1.x support) for the Superdesk journalism platform.
23
+
24
+ ### Key directories
25
+
26
+ - `app-typescript/components/` — ~90 React/TypeScript components (primary deliverable). Each component can have a `.stories.tsx` alongside it.
27
+ - `app-typescript/index.ts` — All React components **must** be exported here for type definitions to be generated.
28
+ - `app/scripts/` — Angular 1.x modules and directives (legacy, do not add new components here).
29
+ - `app/styles/` — SCSS stylesheets (design tokens, component styles).
30
+ - `.storybook/` — Storybook 10 config (`main.ts`, `preview.ts`).
31
+ - `tasks/` — Webpack configurations (dev/prod).
32
+ - `dist/` — Build output (do not edit).
33
+
34
+ ### Build outputs
35
+
36
+ - `dist/superdesk-ui.bundle.js` — UMD bundle (main entry point for consumers)
37
+ - `dist/superdesk-ui.bundle.css` — Extracted CSS
38
+ - `react/index.d.ts` — TypeScript declarations (generated from `app-typescript/index.ts`)
39
+ - `dist/storybook/` — Static Storybook (copied from `storybook-static/` after build)
40
+
41
+ ### Testing
42
+
43
+ Tests use Mocha + Enzyme (adapter for React 16) + jsdom. Test files are co-located with components and match `app-typescript/**/*.spec.*`. Configuration is in `.mocharc.json`.
44
+
45
+ ## React Component Conventions
46
+
47
+ - **TypeScript strict mode** is enforced (`noImplicitAny`, `noUnusedLocals`, etc.).
48
+ - Export every new component from `app-typescript/index.ts`.
49
+ - TSLint is used for `app-typescript/`; ESLint for `app/`.
50
+
51
+ ## Storybook Stories
52
+
53
+ Story files are named `ComponentName.stories.tsx` and placed alongside the component in `app-typescript/components/`.
54
+
55
+ **Critical**: This project uses React 16, which requires explicit React import in every story file that uses JSX:
56
+
57
+ ```typescript
58
+ import React from 'react';
59
+ import type {Meta, StoryObj} from '@storybook/react';
60
+ ```
61
+
62
+ Story format (CSF 3.0):
63
+
64
+ ```typescript
65
+ const meta = {
66
+ title: 'Components/YourComponent',
67
+ component: YourComponent,
68
+ tags: ['autodocs'],
69
+ } satisfies Meta<typeof YourComponent>;
70
+
71
+ export default meta;
72
+ type Story = StoryObj<typeof meta>;
73
+
74
+ export const Playground: Story = {
75
+ args: { /* default props */ },
76
+ };
77
+ ```
78
+
79
+ Every component should have a `Playground` story. See `app-typescript/components/Button.stories.tsx` as the reference implementation.
80
+
81
+ Storybook uses the **Babel compiler** (not SWC) for CI compatibility — do not switch to SWC.
82
+
83
+ ## Storybook Dev Integration
84
+
85
+ In dev mode (`npm start`), Storybook is served from `storybook-static/` at `/storybook/index.html` via webpack-dev-server. Run `npm run build-storybook` first if the storybook link is broken in dev mode.
@@ -412,7 +412,6 @@
412
412
  background-color: var(--color-surface-faded);
413
413
  border-radius: var(--b-radius--full);
414
414
 
415
-
416
415
  .sd-avatar--inline__text {
417
416
  color: var(--color-text);
418
417
  font-size: var(--name-font-size);
@@ -421,7 +420,6 @@
421
420
  overflow: hidden;
422
421
  text-overflow: ellipsis;
423
422
  // max-width: 200px;
424
-
425
423
  }
426
424
  &:has(.sd-avatar--x-small) {
427
425
  gap: var(--gap-0-5);
@@ -435,7 +433,6 @@
435
433
  .sd-avatar--inline__text {
436
434
  --name-font-size: var(--text-size-x-small);
437
435
  padding-inline-end: 1em;
438
-
439
436
  }
440
437
  }
441
438
  &:has(.sd-avatar--medium) {
@@ -1,6 +1,5 @@
1
- @use 'design-tokens/primitives';
2
- @use 'design-tokens/brand-colors';
3
- @use 'design-tokens/semantic-colors';
1
+ @use 'design-tokens/primitives/primitives';
2
+ @use 'design-tokens/semantic/semantics';
3
+ @use 'design-tokens/components/components';
4
4
  @use 'design-tokens/design-tokens-general';
5
- @use 'design-tokens/new-colors';
6
- @use 'design-tokens/component-tokens';
5
+ @use 'deprecate/new-colors';
@@ -2,8 +2,8 @@
2
2
  padding-inline: var(--space--1-5);
3
3
  @include text-overflow;
4
4
  line-height: 1;
5
- border: 1px solid $checkButtonBorderColor;
6
- border-radius: $checkButtonBorderRadius;
5
+ border: 1px solid var(--checkbox-button-color-border-default);
6
+ border-radius: var(--checkbox-button-radius);
7
7
  transition: all 0.2s ease-in-out;
8
8
  display: inline-flex;
9
9
  align-items: center;
@@ -24,7 +24,7 @@
24
24
  }
25
25
 
26
26
  &:hover {
27
- border-color: $checkButtonBorderColorHover;
27
+ border-color: var(--checkbox-button-color-border-hover);
28
28
  box-shadow: 0 1px 4px 0 hsla(0, 0%, 0%, 0.16);
29
29
  color: var(--color-text);
30
30
  }
@@ -233,6 +233,7 @@ $sd-ListItem-column-border: var(--sd-colour-line--x-light);
233
233
  display: flex;
234
234
  flex-direction: column;
235
235
  justify-content: center;
236
+ align-items: center;
236
237
  z-index: 2;
237
238
  opacity: 0;
238
239
  transition: opacity 0.2s linear;
@@ -439,12 +439,21 @@ $photo-nav-transition: all 0.2s ease-out;
439
439
  }
440
440
 
441
441
  .upload__info {
442
+ display: flex;
443
+ flex-direction: column;
444
+ align-items: center;
442
445
  margin: 0 auto;
443
446
  max-width: 40rem;
444
447
  position: relative;
445
448
  inset-block-start: 50%;
446
449
  margin-block-start: -10.6rem;
447
450
  z-index: 1;
451
+ .upload__info-button {
452
+ display: flex;
453
+ margin: 0 auto;
454
+ text-align: center;
455
+ opacity: 0.75;
456
+ }
448
457
  }
449
458
 
450
459
  .upload__info-icon {
@@ -491,13 +500,6 @@ $photo-nav-transition: all 0.2s ease-out;
491
500
  margin-inline-start: -7.8rem;
492
501
  }
493
502
  }
494
- .upload__info-button {
495
- display: block;
496
- margin: 0 auto;
497
- text-align: center;
498
- opacity: 0.75;
499
- }
500
-
501
503
 
502
504
  .sd-photo-preview__thumb-strip {
503
505
  &:hover {
@@ -3,6 +3,21 @@
3
3
  :root {
4
4
  // GENERAL
5
5
  --base-increment: 0.8rem; // 8px
6
+
7
+ // SPACE
8
+ // NEW NAMES
9
+ --space-0: 0; // 0px
10
+ --space-0-5: calc(0.5 * var(--base-increment)); // 4px
11
+ --space-1: calc(1 * var(--base-increment)); // 8px
12
+ --space-1-5: calc(1.5 * var(--base-increment)); // 12px
13
+ --space-2: calc(2 * var(--base-increment)); // 16px
14
+ --space-3: calc(3 * var(--base-increment)); // 24px
15
+ --space-4: calc(4 * var(--base-increment)); // 32px
16
+ --space-5: calc(5 * var(--base-increment)); // 40px;
17
+ --space-6: calc(6 * var(--base-increment)); // 48px;
18
+ --space-7: calc(7 * var(--base-increment)); // 56px;
19
+ --space-8: calc(8 * var(--base-increment)); // 64px;
20
+ // BACKUP FOR OLD NAMES (keep for backwards compatibility)
6
21
  --space--0: 0; // 0px
7
22
  --space--0-5: calc(0.5 * var(--base-increment)); // 4px
8
23
  --space--1: calc(1 * var(--base-increment)); // 8px
@@ -15,26 +30,36 @@
15
30
  --space--7: calc(7 * var(--base-increment)); // 56px;
16
31
  --space--8: calc(8 * var(--base-increment)); // 64px;
17
32
 
18
- --gap--none: 0; // 0px
33
+ // GAP
34
+ // NEW NAMES
19
35
  --gap-0: 0;
20
- --gap--x-small: calc(0.5 * var(--base-increment)); // 4px
21
36
  --gap-0-5: calc(0.5 * var(--base-increment)); // 4px
22
- --gap--small: calc(1 * var(--base-increment)); // 8px
23
37
  --gap-1: calc(1 * var(--base-increment)); // 8px
24
- --gap--medium-small: calc(1.5 * var(--base-increment)); // 12px
25
38
  --gap-1-5: calc(1.5 * var(--base-increment)); // 12px
26
- --gap--medium: calc(2 * var(--base-increment)); // 16px
27
39
  --gap-2: calc(2 * var(--base-increment)); // 16px
40
+ --gap-3: calc(3 * var(--base-increment)); // 24px
41
+ --gap-4: calc(4 * var(--base-increment)); // 32px
42
+ --gap-5: calc(5 * var(--base-increment)); // 40px;
43
+ // BACKUP FOR OLD NAMES (keep for backwards compatibility)
44
+ --gap--none: 0; // 0px
45
+ --gap--x-small: calc(0.5 * var(--base-increment)); // 4px
46
+ --gap--small: calc(1 * var(--base-increment)); // 8px
47
+ --gap--medium-small: calc(1.5 * var(--base-increment)); // 12px
48
+ --gap--medium: calc(2 * var(--base-increment)); // 16px
28
49
  --gap--large: calc(3 * var(--base-increment)); // 24px;
29
- --gap-3: calc(3 * var(--base-increment)); // 24px;
30
50
  --gap--x-large: calc(4 * var(--base-increment)); // 32px;
31
- --gap-4: calc(4 * var(--base-increment)); // 32px;
32
51
  --gap--xx-large: calc(5 * var(--base-increment)); // 40px;
33
- --gap-5: calc(5 * var(--base-increment)); // 40px;
34
-
35
52
  --gap--auto: auto;
36
53
 
37
54
  // BORDER RADIUS
55
+ // NEW NAMES
56
+ --radius-xs: 2px;
57
+ --radius-sm: 3px;
58
+ --radius-md: 4px;
59
+ --radius-lg: 6px;
60
+ --radius-xl: 8px;
61
+ --radius-full: 9999px;
62
+ // BACKUP FOR OLD NAMES (keep for backwards compatibility)
38
63
  --b-radius--x-small: 2px;
39
64
  --b-radius--small: 3px;
40
65
  --b-radius--medium: 4px;
@@ -61,6 +86,16 @@
61
86
  --width__modal--x-large: 80vw;
62
87
 
63
88
  // TEXT SIZE
89
+ // NEW NAMES
90
+ --text-size-base: 1rem;
91
+ --text-size-xxs: calc(var(--text-size-base) * 1); // 10px;
92
+ --text-size-xs: calc(var(--text-size-base) * 1.2); // 12px;
93
+ --text-size-sm: calc(var(--text-size-base) * 1.4); // 14px;
94
+ --text-size-md: calc(var(--text-size-base) * 1.6); // 16px;
95
+ --text-size-lg: calc(var(--text-size-base) * 2); // 20px;
96
+ --text-size-xl: calc(var(--text-size-base) * 2.4); // 24px;
97
+ --text-size-xxl: calc(var(--text-size-base) * 3.2); // 32px;
98
+ // BACKUP FOR OLD NAMES (keep for backwards compatibility)
64
99
  --text-size--base: 1rem;
65
100
  --text-size-xx-small: calc(var(--text-size--base) * 1); // 10px;
66
101
  --text-size-x-small: calc(var(--text-size--base) * 1.2); // 12px;
@@ -92,9 +127,12 @@
92
127
 
93
128
  // FORM ELEMENTS
94
129
  // Size
95
- --form-element-height-default: var(--space--4);
96
- --form-element-height-small: var(--space--3);
97
- --form-element-height-large: var(--space--5);
130
+ --form-element-height-sm: var(--space--3);
131
+ --form-element-height-md: var(--space--4);
132
+ --form-element-height-lg: var(--space--5);
133
+
134
+ --form-element-height-medium: var(--space--4);
135
+ --form-element-height-default: var(--form-element-height-medium);
98
136
 
99
137
  // TRANSITIONS
100
138
  --transition__menu-item: background-color ease 0.1s
@@ -0,0 +1,14 @@
1
+ :root,
2
+ [data-theme="dark-ui"] {
3
+ --checkbox-button-color-text-default: var(--color-text-default);
4
+ --checkbox-button-color-text-checked: var(--color-text-ondark);
5
+ --checkbox-button-color-border-default: var(--color-line-medium);
6
+ --checkbox-button-color-border-hover: var(--color-line-strong);
7
+ --checkbox-button-color-border-checked: lch(0% 0 0 / 0.2);
8
+ --checkbox-button-color-bg-default: transparent;
9
+ --checkbox-button-color-bg-hover: transparent;
10
+ --checkbox-button-color-bg-checked: var(--sd-colour-interactive--active);
11
+ --checkbox-button-radius: var(--radius-sm);
12
+ --checkbox-button-height: var(--form-element-height-default);
13
+ --checkbox-button-color-shadow-focus: var(--sd-colour-interactive-translucent-25);
14
+ }
@@ -0,0 +1,13 @@
1
+ :root,
2
+ [data-theme="dark-ui"] {
3
+ --checkbox-radius: var(--radius-xs);
4
+ --checkbox-color-border-default: var(--color-line-medium);
5
+ --checkbox-color-border-hover: var(--color-line-strong);
6
+ --checkbox-color-border-checked: var(--sd-colour-interactive--active);
7
+ --checkbox-color-bg-default: var(--color-surface-muted);
8
+ --checkbox-color-bg-hover: var(--color-surface-muted);
9
+ --checkbox-color-bg-checked: var(--sd-colour-interactive--active);
10
+ --checkbox-color-text-default: var(--color-text-default);
11
+ --checkbox-color-text-checked: var(--sd-colour-interactive--text);
12
+ --checkbox-color-shadow-focus: var(--sd-colour-interactive-translucent-25);
13
+ }
@@ -0,0 +1,3 @@
1
+ @use 'drag-handle';
2
+ @use 'checkbox';
3
+ @use 'checkbox-button';
@@ -0,0 +1,2 @@
1
+ @use 'colors';
2
+ @use 'brand-colors';
@@ -0,0 +1 @@
1
+ @use 'semantic-colors';