@byline/ui 2.5.2 → 2.6.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.
Files changed (218) hide show
  1. package/dist/components/shimmer/shimmer.d.ts +13 -1
  2. package/dist/components/shimmer/shimmer.js +29 -20
  3. package/dist/components/shimmer/shimmer_module.css +4 -4
  4. package/dist/dnd/draggable-sortable/demo/draggable-list-demo.js +1 -1
  5. package/dist/react.d.ts +18 -54
  6. package/dist/react.js +0 -35
  7. package/dist/styles/styles.css +3 -0
  8. package/dist/uikit.d.ts +1 -0
  9. package/dist/uikit.js +1 -0
  10. package/package.json +2 -8
  11. package/src/components/shimmer/shimmer.module.css +8 -4
  12. package/src/components/shimmer/shimmer.tsx +34 -9
  13. package/src/dnd/draggable-sortable/demo/draggable-list-demo.tsx +1 -1
  14. package/src/react.ts +20 -68
  15. package/src/styles/functional/surfaces.css +13 -1
  16. package/src/uikit.ts +1 -0
  17. package/dist/admin/group.d.ts +0 -27
  18. package/dist/admin/group.js +0 -14
  19. package/dist/admin/group.module.js +0 -6
  20. package/dist/admin/group_module.css +0 -19
  21. package/dist/admin/row.d.ts +0 -25
  22. package/dist/admin/row.js +0 -8
  23. package/dist/admin/row.module.js +0 -5
  24. package/dist/admin/row_module.css +0 -18
  25. package/dist/admin/tabs.d.ts +0 -25
  26. package/dist/admin/tabs.js +0 -35
  27. package/dist/admin/tabs.module.js +0 -10
  28. package/dist/admin/tabs_module.css +0 -68
  29. package/dist/fields/array/array-field.d.ts +0 -14
  30. package/dist/fields/array/array-field.js +0 -176
  31. package/dist/fields/array/array-field.module.js +0 -11
  32. package/dist/fields/array/array-field_module.css +0 -32
  33. package/dist/fields/blocks/blocks-field.d.ts +0 -13
  34. package/dist/fields/blocks/blocks-field.js +0 -244
  35. package/dist/fields/blocks/blocks-field.module.js +0 -26
  36. package/dist/fields/blocks/blocks-field_module.css +0 -107
  37. package/dist/fields/checkbox/checkbox-field.d.ts +0 -16
  38. package/dist/fields/checkbox/checkbox-field.js +0 -28
  39. package/dist/fields/checkbox/checkbox-field.module.js +0 -6
  40. package/dist/fields/checkbox/checkbox-field_module.css +0 -4
  41. package/dist/fields/column-formatter.d.ts +0 -20
  42. package/dist/fields/column-formatter.js +0 -15
  43. package/dist/fields/date-time-formatter.d.ts +0 -16
  44. package/dist/fields/date-time-formatter.js +0 -8
  45. package/dist/fields/datetime/datetime-field.d.ts +0 -16
  46. package/dist/fields/datetime/datetime-field.js +0 -37
  47. package/dist/fields/datetime/datetime-field.module.js +0 -5
  48. package/dist/fields/datetime/datetime-field_module.css +0 -4
  49. package/dist/fields/draggable-context-menu.d.ts +0 -6
  50. package/dist/fields/draggable-context-menu.js +0 -83
  51. package/dist/fields/draggable-context-menu.module.js +0 -15
  52. package/dist/fields/draggable-context-menu_module.css +0 -91
  53. package/dist/fields/field-helpers.d.ts +0 -26
  54. package/dist/fields/field-helpers.js +0 -50
  55. package/dist/fields/field-renderer.d.ts +0 -37
  56. package/dist/fields/field-renderer.js +0 -206
  57. package/dist/fields/field-renderer.module.js +0 -8
  58. package/dist/fields/field-renderer_module.css +0 -11
  59. package/dist/fields/file/file-field.d.ts +0 -19
  60. package/dist/fields/file/file-field.js +0 -226
  61. package/dist/fields/file/file-field.module.js +0 -18
  62. package/dist/fields/file/file-field_module.css +0 -131
  63. package/dist/fields/file/file-upload-field.d.ts +0 -21
  64. package/dist/fields/file/file-upload-field.js +0 -128
  65. package/dist/fields/file/file-upload-field.module.js +0 -15
  66. package/dist/fields/file/file-upload-field_module.css +0 -74
  67. package/dist/fields/group/group-field.d.ts +0 -15
  68. package/dist/fields/group/group-field.js +0 -59
  69. package/dist/fields/group/group-field.module.js +0 -9
  70. package/dist/fields/group/group-field_module.css +0 -27
  71. package/dist/fields/image/image-field.d.ts +0 -19
  72. package/dist/fields/image/image-field.js +0 -242
  73. package/dist/fields/image/image-field.module.js +0 -22
  74. package/dist/fields/image/image-field_module.css +0 -121
  75. package/dist/fields/image/image-upload-field.d.ts +0 -21
  76. package/dist/fields/image/image-upload-field.js +0 -187
  77. package/dist/fields/image/image-upload-field.module.js +0 -19
  78. package/dist/fields/image/image-upload-field_module.css +0 -92
  79. package/dist/fields/local-date-time.d.ts +0 -27
  80. package/dist/fields/local-date-time.js +0 -49
  81. package/dist/fields/locale-badge.d.ts +0 -18
  82. package/dist/fields/locale-badge.js +0 -10
  83. package/dist/fields/locale-badge.module.js +0 -5
  84. package/dist/fields/locale-badge_module.css +0 -27
  85. package/dist/fields/numerical/numerical-field.d.ts +0 -18
  86. package/dist/fields/numerical/numerical-field.js +0 -74
  87. package/dist/fields/relation/relation-display.d.ts +0 -40
  88. package/dist/fields/relation/relation-display.js +0 -58
  89. package/dist/fields/relation/relation-display.module.js +0 -9
  90. package/dist/fields/relation/relation-display_module.css +0 -21
  91. package/dist/fields/relation/relation-field.d.ts +0 -18
  92. package/dist/fields/relation/relation-field.js +0 -146
  93. package/dist/fields/relation/relation-field.module.js +0 -13
  94. package/dist/fields/relation/relation-field_module.css +0 -62
  95. package/dist/fields/relation/relation-picker.d.ts +0 -49
  96. package/dist/fields/relation/relation-picker.js +0 -233
  97. package/dist/fields/relation/relation-picker.module.js +0 -26
  98. package/dist/fields/relation/relation-picker_module.css +0 -124
  99. package/dist/fields/relation/relation-summary.d.ts +0 -31
  100. package/dist/fields/relation/relation-summary.js +0 -50
  101. package/dist/fields/relation/relation-summary.module.js +0 -11
  102. package/dist/fields/relation/relation-summary_module.css +0 -37
  103. package/dist/fields/select/select-field.d.ts +0 -16
  104. package/dist/fields/select/select-field.js +0 -50
  105. package/dist/fields/select/select-field.module.js +0 -5
  106. package/dist/fields/select/select-field_module.css +0 -4
  107. package/dist/fields/sortable-item.d.ts +0 -15
  108. package/dist/fields/sortable-item.js +0 -80
  109. package/dist/fields/sortable-item.module.js +0 -22
  110. package/dist/fields/sortable-item_module.css +0 -124
  111. package/dist/fields/text/text-field.d.ts +0 -20
  112. package/dist/fields/text/text-field.js +0 -104
  113. package/dist/fields/text/text-field.module.js +0 -6
  114. package/dist/fields/text/text-field_module.css +0 -5
  115. package/dist/fields/text-area/text-area-field.d.ts +0 -20
  116. package/dist/fields/text-area/text-area-field.js +0 -105
  117. package/dist/fields/text-area/text-area-field.module.js +0 -6
  118. package/dist/fields/text-area/text-area-field_module.css +0 -5
  119. package/dist/fields/use-field-change-handler.d.ts +0 -23
  120. package/dist/fields/use-field-change-handler.js +0 -52
  121. package/dist/forms/document-actions.d.ts +0 -48
  122. package/dist/forms/document-actions.js +0 -469
  123. package/dist/forms/document-actions.module.js +0 -34
  124. package/dist/forms/document-actions_module.css +0 -118
  125. package/dist/forms/form-context.d.ts +0 -89
  126. package/dist/forms/form-context.js +0 -466
  127. package/dist/forms/form-renderer.d.ts +0 -98
  128. package/dist/forms/form-renderer.js +0 -591
  129. package/dist/forms/form-renderer.module.js +0 -46
  130. package/dist/forms/form-renderer_module.css +0 -245
  131. package/dist/forms/navigation-guard.d.ts +0 -54
  132. package/dist/forms/navigation-guard.js +0 -22
  133. package/dist/forms/path-widget.d.ts +0 -36
  134. package/dist/forms/path-widget.js +0 -107
  135. package/dist/forms/path-widget.module.js +0 -8
  136. package/dist/forms/path-widget_module.css +0 -29
  137. package/dist/forms/upload-executor.d.ts +0 -57
  138. package/dist/forms/upload-executor.js +0 -92
  139. package/dist/services/field-services-context.d.ts +0 -16
  140. package/dist/services/field-services-context.js +0 -13
  141. package/dist/services/field-services-types.d.ts +0 -63
  142. package/dist/services/field-services-types.js +0 -1
  143. package/dist/widgets/diff-viewer/diff-modal.d.ts +0 -22
  144. package/dist/widgets/diff-viewer/diff-modal.js +0 -146
  145. package/dist/widgets/diff-viewer/diff-modal.module.js +0 -14
  146. package/dist/widgets/diff-viewer/diff-modal_module.css +0 -56
  147. package/dist/widgets/status-badge/status-badge.d.ts +0 -25
  148. package/dist/widgets/status-badge/status-badge.js +0 -35
  149. package/dist/widgets/status-badge/status-badge.module.js +0 -7
  150. package/dist/widgets/status-badge/status-badge_module.css +0 -20
  151. package/src/admin/group.module.css +0 -41
  152. package/src/admin/group.tsx +0 -40
  153. package/src/admin/row.module.css +0 -32
  154. package/src/admin/row.tsx +0 -33
  155. package/src/admin/tabs.module.css +0 -107
  156. package/src/admin/tabs.tsx +0 -82
  157. package/src/fields/array/array-field.module.css +0 -48
  158. package/src/fields/array/array-field.tsx +0 -266
  159. package/src/fields/blocks/blocks-field.module.css +0 -148
  160. package/src/fields/blocks/blocks-field.tsx +0 -312
  161. package/src/fields/checkbox/checkbox-field.module.css +0 -4
  162. package/src/fields/checkbox/checkbox-field.tsx +0 -54
  163. package/src/fields/column-formatter.tsx +0 -31
  164. package/src/fields/date-time-formatter.tsx +0 -22
  165. package/src/fields/datetime/datetime-field.module.css +0 -13
  166. package/src/fields/datetime/datetime-field.tsx +0 -54
  167. package/src/fields/draggable-context-menu.module.css +0 -127
  168. package/src/fields/draggable-context-menu.tsx +0 -85
  169. package/src/fields/field-helpers.ts +0 -69
  170. package/src/fields/field-renderer.module.css +0 -22
  171. package/src/fields/field-renderer.tsx +0 -288
  172. package/src/fields/file/file-field.module.css +0 -153
  173. package/src/fields/file/file-field.tsx +0 -271
  174. package/src/fields/file/file-upload-field.module.css +0 -101
  175. package/src/fields/file/file-upload-field.tsx +0 -183
  176. package/src/fields/group/group-field.module.css +0 -43
  177. package/src/fields/group/group-field.tsx +0 -84
  178. package/src/fields/image/image-field.module.css +0 -155
  179. package/src/fields/image/image-field.tsx +0 -291
  180. package/src/fields/image/image-upload-field.module.css +0 -123
  181. package/src/fields/image/image-upload-field.tsx +0 -270
  182. package/src/fields/local-date-time.tsx +0 -88
  183. package/src/fields/locale-badge.module.css +0 -37
  184. package/src/fields/locale-badge.tsx +0 -32
  185. package/src/fields/numerical/numerical-field.tsx +0 -114
  186. package/src/fields/relation/relation-display.module.css +0 -36
  187. package/src/fields/relation/relation-display.tsx +0 -130
  188. package/src/fields/relation/relation-field.module.css +0 -83
  189. package/src/fields/relation/relation-field.tsx +0 -206
  190. package/src/fields/relation/relation-picker.module.css +0 -168
  191. package/src/fields/relation/relation-picker.tsx +0 -325
  192. package/src/fields/relation/relation-summary.module.css +0 -55
  193. package/src/fields/relation/relation-summary.tsx +0 -123
  194. package/src/fields/select/select-field.module.css +0 -13
  195. package/src/fields/select/select-field.tsx +0 -61
  196. package/src/fields/sortable-item.module.css +0 -167
  197. package/src/fields/sortable-item.tsx +0 -101
  198. package/src/fields/text/text-field.module.css +0 -13
  199. package/src/fields/text/text-field.tsx +0 -146
  200. package/src/fields/text-area/text-area-field.module.css +0 -13
  201. package/src/fields/text-area/text-area-field.tsx +0 -147
  202. package/src/fields/use-field-change-handler.ts +0 -112
  203. package/src/forms/document-actions.module.css +0 -160
  204. package/src/forms/document-actions.tsx +0 -487
  205. package/src/forms/form-context.tsx +0 -704
  206. package/src/forms/form-renderer.module.css +0 -321
  207. package/src/forms/form-renderer.tsx +0 -888
  208. package/src/forms/navigation-guard.tsx +0 -98
  209. package/src/forms/path-widget.module.css +0 -41
  210. package/src/forms/path-widget.test.tsx +0 -217
  211. package/src/forms/path-widget.tsx +0 -181
  212. package/src/forms/upload-executor.ts +0 -190
  213. package/src/services/field-services-context.tsx +0 -35
  214. package/src/services/field-services-types.ts +0 -68
  215. package/src/widgets/diff-viewer/diff-modal.module.css +0 -79
  216. package/src/widgets/diff-viewer/diff-modal.tsx +0 -184
  217. package/src/widgets/status-badge/status-badge.module.css +0 -31
  218. package/src/widgets/status-badge/status-badge.tsx +0 -69
@@ -1,160 +0,0 @@
1
- /**
2
- * DocumentActions — overflow menu (Unpublish / Delete) on the form chrome.
3
- *
4
- * Override handles:
5
- * .byline-form-actions-icon — the rotated ellipsis trigger icon
6
- * .byline-form-actions-menu — dropdown content panel
7
- * .byline-form-actions-item — a row inside the dropdown
8
- * .byline-form-actions-item-icon — fixed-width icon column
9
- * .byline-form-actions-item-text — label column
10
- * .byline-form-actions-delete — destructive label colour
11
- * .byline-form-actions-modal-head — modal header layout
12
- * .byline-form-actions-modal-title — modal heading text
13
- * .byline-form-actions-sr-only — visually-hidden autofocus shim
14
- */
15
-
16
- .icon,
17
- :global(.byline-form-actions-icon) {
18
- transform: rotate(90deg);
19
- color: var(--primary-500);
20
- }
21
-
22
- .menu,
23
- :global(.byline-form-actions-menu) {
24
- min-width: 140px;
25
- }
26
-
27
- .item,
28
- :global(.byline-form-actions-item) {
29
- display: flex;
30
- align-items: center;
31
- margin-left: var(--spacing-8);
32
- }
33
-
34
- .item-icon,
35
- :global(.byline-form-actions-item-icon) {
36
- display: inline-block;
37
- width: 28px;
38
- }
39
-
40
- .item-text,
41
- :global(.byline-form-actions-item-text) {
42
- display: inline-block;
43
- width: 100%;
44
- flex: 1;
45
- font-size: var(--font-size-sm);
46
- text-align: left;
47
- }
48
-
49
- .delete,
50
- :global(.byline-form-actions-delete) {
51
- flex: 1;
52
- width: 100%;
53
- border: none;
54
- background: none;
55
- padding: 0;
56
- color: var(--red-600);
57
- line-height: 1;
58
- text-align: left;
59
- cursor: pointer;
60
- }
61
-
62
- .modal-head,
63
- :global(.byline-form-actions-modal-head) {
64
- padding-top: 1rem;
65
- margin-bottom: var(--spacing-8);
66
- }
67
-
68
- .modal-title,
69
- :global(.byline-form-actions-modal-title) {
70
- margin: 0 0 var(--spacing-8) 0;
71
- font-size: var(--font-size-2xl);
72
- }
73
-
74
- .sr-only,
75
- :global(.byline-form-actions-sr-only) {
76
- position: absolute;
77
- width: 1px;
78
- height: 1px;
79
- padding: 0;
80
- margin: -1px;
81
- overflow: hidden;
82
- clip: rect(0, 0, 0, 0);
83
- white-space: nowrap;
84
- border: 0;
85
- }
86
-
87
- .list,
88
- :global(.byline-form-actions-list) {
89
- margin: var(--spacing-8) 0;
90
- padding-left: 1.25rem;
91
- font-size: var(--font-size-sm);
92
- }
93
-
94
- .preview,
95
- :global(.byline-form-actions-preview) {
96
- margin-top: var(--spacing-16);
97
- padding: var(--spacing-8) var(--spacing-12);
98
- background: var(--surface-2, rgba(0, 0, 0, 0.03));
99
- border: 1px solid var(--border-subtle, rgba(0, 0, 0, 0.08));
100
- border-radius: var(--radius-md, 4px);
101
- font-size: var(--font-size-sm);
102
- }
103
-
104
- .preview-label,
105
- :global(.byline-form-actions-preview-label) {
106
- font-weight: 500;
107
- margin-bottom: var(--spacing-4);
108
- opacity: 0.75;
109
- }
110
-
111
- .preview-row,
112
- :global(.byline-form-actions-preview-row) {
113
- display: flex;
114
- align-items: center;
115
- gap: var(--spacing-8);
116
- flex-wrap: wrap;
117
- }
118
-
119
- .preview-before,
120
- :global(.byline-form-actions-preview-before) {
121
- font-family: var(--font-mono, monospace);
122
- opacity: 0.7;
123
- }
124
-
125
- .preview-arrow,
126
- :global(.byline-form-actions-preview-arrow) {
127
- opacity: 0.5;
128
- }
129
-
130
- .preview-after,
131
- :global(.byline-form-actions-preview-after) {
132
- font-family: var(--font-mono, monospace);
133
- font-weight: 500;
134
- }
135
-
136
- .copy-row,
137
- :global(.byline-form-actions-copy-row) {
138
- display: flex;
139
- align-items: center;
140
- flex-wrap: wrap;
141
- }
142
-
143
- .copy-label,
144
- :global(.byline-form-actions-copy-label) {
145
- /* Layout-only handle; spacing is set inline alongside the field. */
146
- }
147
-
148
- .copy-source,
149
- :global(.byline-form-actions-copy-source) {
150
- font-family: var(--font-mono, monospace);
151
- }
152
-
153
- /* ─── Dark theme variants ───────────────────────────────────── */
154
-
155
- :is([data-theme="dark"], :global(.dark)) {
156
- .delete,
157
- :global(.byline-form-actions-delete) {
158
- color: var(--red-400);
159
- }
160
- }
@@ -1,487 +0,0 @@
1
- 'use client'
2
-
3
- /**
4
- * This Source Code is subject to the terms of the Mozilla Public
5
- * License, v. 2.0. If a copy of the MPL was not distributed with this
6
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
- *
8
- * Copyright (c) Infonomic Company Limited
9
- */
10
-
11
- import { useState } from 'react'
12
-
13
- import cx from 'classnames'
14
-
15
- import {
16
- Button,
17
- Checkbox,
18
- CloseIcon,
19
- DeleteIcon,
20
- Dropdown as DropdownComponent,
21
- EllipsisIcon,
22
- IconButton,
23
- Modal,
24
- Select,
25
- } from '../uikit.js'
26
- import styles from './document-actions.module.css'
27
- import type { PublishedVersionInfo } from './form-renderer'
28
-
29
- const DUPLICATE_TITLE_SUFFIX = ' (copy)'
30
-
31
- /**
32
- * Shape of a content-locale option as consumed by the Copy-to-Locale
33
- * modal. Matches the host adapter's `ContentLocaleOption`; declared
34
- * locally so this package does not take a dependency on host code.
35
- */
36
- export interface DocumentActionsLocaleOption {
37
- code: string
38
- label: string
39
- }
40
-
41
- export function DocumentActions({
42
- publishedVersion,
43
- onUnpublish,
44
- onDelete,
45
- onDuplicate,
46
- sourceTitle,
47
- onCopyToLocale,
48
- sourceLocale,
49
- contentLocales,
50
- }: {
51
- publishedVersion?: PublishedVersionInfo | null
52
- onUnpublish?: () => Promise<void>
53
- onDelete?: () => Promise<void>
54
- /**
55
- * Called when the editor confirms the duplicate modal. The parent runs
56
- * the server fn, surfaces a toast, and navigates to the new document.
57
- */
58
- onDuplicate?: () => Promise<void>
59
- /**
60
- * The current (saved) value of the source document's `useAsTitle`
61
- * field, used to render the suffix preview inside the duplicate modal.
62
- * Sourced from the form's `initialData`, not live form state, so the
63
- * preview reflects what will actually be duplicated.
64
- */
65
- sourceTitle?: string | null
66
- /**
67
- * Called when the editor confirms the Copy-to-Locale modal. The
68
- * parent runs the server fn, surfaces a toast, and navigates to the
69
- * target locale view. Menu item is hidden when omitted, or when fewer
70
- * than two content locales are configured.
71
- */
72
- onCopyToLocale?: (args: { targetLocale: string; overwrite: boolean }) => Promise<void>
73
- /**
74
- * The locale the form is currently displaying. Used as the read-only
75
- * "From" label in the Copy-to-Locale modal and excluded from the
76
- * target Select.
77
- */
78
- sourceLocale?: string
79
- /**
80
- * All configured content locales (code + display label). The
81
- * Copy-to-Locale Select lists every locale except `sourceLocale`.
82
- */
83
- contentLocales?: ReadonlyArray<DocumentActionsLocaleOption>
84
- }) {
85
- const [showDeleteConfirm, setShowDeleteConfirm] = useState(false)
86
- const [showDuplicateConfirm, setShowDuplicateConfirm] = useState(false)
87
- const [duplicateBusy, setDuplicateBusy] = useState(false)
88
-
89
- // Copy-to-Locale modal state. The menu item is hidden entirely unless
90
- // the host has supplied a handler AND there is at least one *other*
91
- // locale to copy into.
92
- const availableTargetLocales = (contentLocales ?? []).filter((loc) => loc.code !== sourceLocale)
93
- const copyToLocaleAvailable = onCopyToLocale != null && availableTargetLocales.length > 0
94
- const [showCopyToLocaleConfirm, setShowCopyToLocaleConfirm] = useState(false)
95
- const [copyToLocaleBusy, setCopyToLocaleBusy] = useState(false)
96
- const [copyTargetLocale, setCopyTargetLocale] = useState<string>(
97
- availableTargetLocales[0]?.code ?? ''
98
- )
99
- const [copyOverwrite, setCopyOverwrite] = useState(false)
100
-
101
- const handleOnDelete = () => {
102
- setShowDeleteConfirm(false)
103
- if (onDelete) {
104
- onDelete()
105
- }
106
- }
107
-
108
- const handleOnDuplicate = async () => {
109
- if (!onDuplicate) return
110
- setDuplicateBusy(true)
111
- try {
112
- await onDuplicate()
113
- setShowDuplicateConfirm(false)
114
- } finally {
115
- setDuplicateBusy(false)
116
- }
117
- }
118
-
119
- const handleOpenCopyToLocale = () => {
120
- // Reset on open: pick the first available target and clear the
121
- // overwrite checkbox so a previous-session "overwrite=true" choice
122
- // is not silently sticky.
123
- setCopyTargetLocale(availableTargetLocales[0]?.code ?? '')
124
- setCopyOverwrite(false)
125
- setShowCopyToLocaleConfirm(true)
126
- }
127
-
128
- const handleOnCopyToLocale = async () => {
129
- if (!onCopyToLocale || !copyTargetLocale) return
130
- setCopyToLocaleBusy(true)
131
- try {
132
- await onCopyToLocale({ targetLocale: copyTargetLocale, overwrite: copyOverwrite })
133
- setShowCopyToLocaleConfirm(false)
134
- } finally {
135
- setCopyToLocaleBusy(false)
136
- }
137
- }
138
-
139
- // Preview text shown inside the modal. Falls back to the literal suffix
140
- // when no source title is supplied (collections without `useAsTitle`).
141
- const duplicatePreviewBefore = sourceTitle ?? ''
142
- const duplicatePreviewAfter = (sourceTitle ?? '') + DUPLICATE_TITLE_SUFFIX
143
-
144
- const sourceLocaleLabel =
145
- contentLocales?.find((loc) => loc.code === sourceLocale)?.label ?? sourceLocale ?? ''
146
-
147
- return (
148
- <>
149
- <DropdownComponent.Root>
150
- <DropdownComponent.Trigger
151
- render={<IconButton variant="text" intent="noeffect" size="sm" />}
152
- >
153
- <EllipsisIcon
154
- className={cx('byline-form-actions-icon', styles.icon)}
155
- width="15px"
156
- height="15px"
157
- />
158
- </DropdownComponent.Trigger>
159
-
160
- <DropdownComponent.Portal>
161
- <DropdownComponent.Content
162
- className={cx('byline-form-actions-menu', styles.menu)}
163
- align="end"
164
- data-side="top"
165
- sideOffset={10}
166
- >
167
- {/*{publishedVersion && (
168
- <>
169
- <DropdownComponent.Item onClick={onUnpublish}>
170
- <div className={cx('byline-form-actions-item', styles.item)}>
171
- <span className={cx('byline-form-actions-item-icon', styles['item-icon'])} />
172
- <span className={cx('byline-form-actions-item-text', styles['item-text'])}>
173
- Unpublish
174
- </span>
175
- </div>
176
- </DropdownComponent.Item>
177
- <DropdownComponent.Separator />
178
- </>
179
- )}*/}
180
- {copyToLocaleAvailable && (
181
- <DropdownComponent.Item onClick={handleOpenCopyToLocale}>
182
- <div className={cx('byline-form-actions-item', styles.item)}>
183
- <span className={cx('byline-form-actions-item-text', styles['item-text'])}>
184
- <button type="button">Copy to Locale</button>
185
- </span>
186
- </div>
187
- </DropdownComponent.Item>
188
- )}
189
- {onDuplicate && (
190
- <DropdownComponent.Item
191
- onClick={() => {
192
- setShowDuplicateConfirm(true)
193
- }}
194
- >
195
- <div className={cx('byline-form-actions-item', styles.item)}>
196
- <span className={cx('byline-form-actions-item-text', styles['item-text'])}>
197
- <button type="button">Duplicate</button>
198
- </span>
199
- </div>
200
- </DropdownComponent.Item>
201
- )}
202
- <DropdownComponent.Separator />
203
- <DropdownComponent.Item
204
- onClick={() => {
205
- setShowDeleteConfirm(true)
206
- }}
207
- >
208
- <div className={cx('byline-form-actions-item', styles.item)}>
209
- <span className={cx('byline-form-actions-item-icon', styles['item-icon'])}>
210
- <DeleteIcon width="16px" height="16px" />
211
- </span>
212
- <span className={cx('byline-form-actions-item-text', styles['item-text'])}>
213
- <button type="button" className={cx('byline-form-actions-delete', styles.delete)}>
214
- Delete
215
- </button>
216
- </span>
217
- </div>
218
- </DropdownComponent.Item>
219
- </DropdownComponent.Content>
220
- </DropdownComponent.Portal>
221
- </DropdownComponent.Root>
222
-
223
- <Modal
224
- isOpen={showDeleteConfirm}
225
- closeOnOverlayClick={true}
226
- onDismiss={() => {
227
- setShowDeleteConfirm(false)
228
- }}
229
- >
230
- <Modal.Container style={{ maxWidth: '500px' }}>
231
- <Modal.Header className={cx('byline-form-actions-modal-head', styles['modal-head'])}>
232
- <h3 className={cx('byline-form-actions-modal-title', styles['modal-title'])}>
233
- Delete Document
234
- </h3>
235
- <IconButton
236
- arial-label="Close"
237
- size="xs"
238
- onClick={() => {
239
- setShowDeleteConfirm(false)
240
- }}
241
- >
242
- <CloseIcon width="16px" height="16px" svgClassName="white-icon" />
243
- </IconButton>
244
- </Modal.Header>
245
- <Modal.Content>
246
- <p>
247
- Warning: This action cannot be undone. Are you sure you want to delete this document?
248
- </p>
249
- </Modal.Content>
250
- <Modal.Actions>
251
- <button
252
- data-autofocus
253
- type="button"
254
- tabIndex={0}
255
- className={cx('byline-form-actions-sr-only', styles['sr-only'])}
256
- >
257
- no action
258
- </button>
259
- <Button
260
- size="sm"
261
- style={{ minWidth: '80px' }}
262
- intent="noeffect"
263
- onClick={() => {
264
- setShowDeleteConfirm(false)
265
- }}
266
- >
267
- Cancel
268
- </Button>
269
- <Button size="sm" style={{ minWidth: '80px' }} intent="danger" onClick={handleOnDelete}>
270
- Delete
271
- </Button>
272
- </Modal.Actions>
273
- </Modal.Container>
274
- </Modal>
275
-
276
- <Modal
277
- isOpen={showDuplicateConfirm}
278
- closeOnOverlayClick={!duplicateBusy}
279
- onDismiss={() => {
280
- if (!duplicateBusy) setShowDuplicateConfirm(false)
281
- }}
282
- >
283
- <Modal.Container style={{ maxWidth: '560px' }}>
284
- <Modal.Header className={cx('byline-form-actions-modal-head', styles['modal-head'])}>
285
- <h3 className={cx('byline-form-actions-modal-title', styles['modal-title'])}>
286
- Duplicate Document
287
- </h3>
288
- <IconButton
289
- arial-label="Close"
290
- size="xs"
291
- onClick={() => {
292
- if (!duplicateBusy) setShowDuplicateConfirm(false)
293
- }}
294
- >
295
- <CloseIcon width="16px" height="16px" svgClassName="white-icon" />
296
- </IconButton>
297
- </Modal.Header>
298
- <Modal.Content className="prose">
299
- <p className="m-0">
300
- A new document will be created with all translations (if any) cloned from this one.
301
- After the duplicate is created you should:
302
- </p>
303
- <ul className={cx('byline-form-actions-list', styles.list)}>
304
- <li>
305
- Update the title of the docuiment (including any translated versions). The title is
306
- currently suffixed with <code>{DUPLICATE_TITLE_SUFFIX.trim()}</code>.
307
- </li>
308
- <li>
309
- Review the system path in the path widget — the auto-generated path will reflect the
310
- suffixed title and is unlikely to be what you want long-term.
311
- </li>
312
- </ul>
313
- {sourceTitle != null && sourceTitle.length > 0 && (
314
- <div className={cx('byline-form-actions-preview', styles.preview)}>
315
- <div className={cx('byline-form-actions-preview-label', styles['preview-label'])}>
316
- Preview (current locale):
317
- </div>
318
- <div className={cx('byline-form-actions-preview-row', styles['preview-row'])}>
319
- <span
320
- className={cx('byline-form-actions-preview-before', styles['preview-before'])}
321
- >
322
- {duplicatePreviewBefore}
323
- </span>
324
- <span
325
- className={cx('byline-form-actions-preview-arrow', styles['preview-arrow'])}
326
- >
327
-
328
- </span>
329
- <span
330
- className={cx('byline-form-actions-preview-after', styles['preview-after'])}
331
- >
332
- {duplicatePreviewAfter}
333
- </span>
334
- </div>
335
- </div>
336
- )}
337
- </Modal.Content>
338
- <Modal.Actions>
339
- <button
340
- data-autofocus
341
- type="button"
342
- tabIndex={0}
343
- className={cx('byline-form-actions-sr-only', styles['sr-only'])}
344
- >
345
- no action
346
- </button>
347
- <Button
348
- size="sm"
349
- style={{ minWidth: '80px' }}
350
- intent="noeffect"
351
- onClick={() => {
352
- if (!duplicateBusy) setShowDuplicateConfirm(false)
353
- }}
354
- disabled={duplicateBusy}
355
- >
356
- Cancel
357
- </Button>
358
- <Button
359
- size="sm"
360
- style={{ minWidth: '80px' }}
361
- intent="primary"
362
- onClick={handleOnDuplicate}
363
- disabled={duplicateBusy}
364
- >
365
- {duplicateBusy ? 'Duplicating...' : 'Duplicate'}
366
- </Button>
367
- </Modal.Actions>
368
- </Modal.Container>
369
- </Modal>
370
-
371
- <Modal
372
- isOpen={showCopyToLocaleConfirm}
373
- closeOnOverlayClick={!copyToLocaleBusy}
374
- onDismiss={() => {
375
- if (!copyToLocaleBusy) setShowCopyToLocaleConfirm(false)
376
- }}
377
- >
378
- <Modal.Container style={{ maxWidth: '560px' }}>
379
- <Modal.Header className={cx('byline-form-actions-modal-head', styles['modal-head'])}>
380
- <h3 className={cx('byline-form-actions-modal-title', styles['modal-title'])}>
381
- Copy to Locale
382
- </h3>
383
- <IconButton
384
- arial-label="Close"
385
- size="xs"
386
- onClick={() => {
387
- if (!copyToLocaleBusy) setShowCopyToLocaleConfirm(false)
388
- }}
389
- >
390
- <CloseIcon width="16px" height="16px" svgClassName="white-icon" />
391
- </IconButton>
392
- </Modal.Header>
393
- <Modal.Content>
394
- <p>
395
- Copy this document's content from one locale to another. Non-localized fields are
396
- shared across locales and will not change.
397
- </p>
398
- <div
399
- className={cx('byline-form-actions-copy-row', styles['copy-row'])}
400
- style={{ marginTop: 'var(--spacing-12)' }}
401
- >
402
- <span
403
- className={cx('byline-form-actions-copy-label', styles['copy-label'])}
404
- style={{ fontWeight: 500 }}
405
- >
406
- From:&nbsp;
407
- </span>
408
- <span className={cx('byline-form-actions-copy-source', styles['copy-source'])}>
409
- {sourceLocaleLabel}
410
- </span>
411
- </div>
412
- <div
413
- className={cx('byline-form-actions-copy-row', styles['copy-row'])}
414
- style={{ marginTop: 'var(--spacing-12)' }}
415
- >
416
- <span
417
- className={cx('byline-form-actions-copy-label', styles['copy-label'])}
418
- style={{ fontWeight: 500, marginRight: 'var(--spacing-8)' }}
419
- >
420
- To:
421
- </span>
422
- <Select<string>
423
- size="sm"
424
- ariaLabel="Target locale"
425
- value={copyTargetLocale}
426
- items={availableTargetLocales.map((loc) => ({
427
- value: loc.code,
428
- label: loc.label,
429
- }))}
430
- onValueChange={(value) => {
431
- if (value != null) setCopyTargetLocale(value)
432
- }}
433
- disabled={copyToLocaleBusy}
434
- />
435
- </div>
436
- <div
437
- className={cx('byline-form-actions-copy-row', styles['copy-row'])}
438
- style={{ marginTop: 'var(--spacing-16)' }}
439
- >
440
- <Checkbox
441
- id="copy-to-locale-overwrite"
442
- name="overwrite"
443
- label="Overwrite existing field data in target locale"
444
- checked={copyOverwrite}
445
- disabled={copyToLocaleBusy}
446
- helpText="Unchecked: only fill in target fields that are currently empty. Checked: replace every translated field with the source's value."
447
- onCheckedChange={(value) => {
448
- setCopyOverwrite(value === true)
449
- }}
450
- />
451
- </div>
452
- </Modal.Content>
453
- <Modal.Actions>
454
- <button
455
- data-autofocus
456
- type="button"
457
- tabIndex={0}
458
- className={cx('byline-form-actions-sr-only', styles['sr-only'])}
459
- >
460
- no action
461
- </button>
462
- <Button
463
- size="sm"
464
- style={{ minWidth: '80px' }}
465
- intent="noeffect"
466
- onClick={() => {
467
- if (!copyToLocaleBusy) setShowCopyToLocaleConfirm(false)
468
- }}
469
- disabled={copyToLocaleBusy}
470
- >
471
- Cancel
472
- </Button>
473
- <Button
474
- size="sm"
475
- style={{ minWidth: '80px' }}
476
- intent="primary"
477
- onClick={handleOnCopyToLocale}
478
- disabled={copyToLocaleBusy || !copyTargetLocale}
479
- >
480
- {copyToLocaleBusy ? 'Copying...' : 'Copy'}
481
- </Button>
482
- </Modal.Actions>
483
- </Modal.Container>
484
- </Modal>
485
- </>
486
- )
487
- }