@dyrected/admin 2.6.1 → 2.6.2

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 (46) hide show
  1. package/dist/admin.css +120 -28
  2. package/dist/components/forms/field-renderer.d.ts +3 -9
  3. package/dist/components/forms/fields/date-picker.d.ts +4 -1
  4. package/dist/components/forms/fields/format-aware-inputs.test.d.ts +1 -0
  5. package/dist/components/forms/fields/text-field.d.ts +1 -1
  6. package/dist/components/forms/fields/url-field.d.ts +1 -1
  7. package/dist/components/media/__tests__/media-library-dialog.test.d.ts +1 -0
  8. package/dist/components/media/storage-notice.d.ts +7 -0
  9. package/dist/controllers/__tests__/field.test.d.ts +1 -0
  10. package/dist/controllers/__tests__/form.test.d.ts +1 -0
  11. package/dist/controllers/__tests__/media.test.d.ts +1 -0
  12. package/dist/controllers/__tests__/theme.test.d.ts +1 -0
  13. package/dist/controllers/field.d.ts +13 -0
  14. package/dist/controllers/form.d.ts +102 -0
  15. package/dist/controllers/media.d.ts +119 -0
  16. package/dist/controllers/theme.d.ts +28 -0
  17. package/dist/favicon.ico +0 -0
  18. package/dist/favicon.svg +85 -1
  19. package/dist/hooks/__tests__/use-add-media-from-url.test.d.ts +1 -0
  20. package/dist/hooks/__tests__/use-field.test.d.ts +1 -0
  21. package/dist/hooks/admin-theme-context.d.ts +2 -8
  22. package/dist/hooks/admin-theme-provider.d.ts +3 -1
  23. package/dist/hooks/admin-theme.d.ts +1 -0
  24. package/dist/hooks/use-add-media-from-url.d.ts +8 -17
  25. package/dist/hooks/use-admin-theme.d.ts +2 -1
  26. package/dist/hooks/use-dyrected-form.d.ts +2 -0
  27. package/dist/hooks/use-field.d.ts +2 -0
  28. package/dist/hooks/use-media-library.d.ts +26 -0
  29. package/dist/hooks/use-media-upload.d.ts +20 -0
  30. package/dist/hooks/use-media-url.d.ts +20 -0
  31. package/dist/index.d.ts +30 -3
  32. package/dist/index.mjs +1438 -1556
  33. package/dist/lib/__tests__/external-media.test.d.ts +1 -0
  34. package/dist/lib/__tests__/media-utils.test.d.ts +1 -0
  35. package/dist/lib/compress-image.d.ts +9 -0
  36. package/dist/lib/external-media.d.ts +9 -4
  37. package/dist/lib/media-utils.d.ts +26 -0
  38. package/dist/lib/workflow-ui.d.ts +1 -0
  39. package/dist/providers/dyrected-form-context.d.ts +14 -0
  40. package/dist/public/contracts.d.ts +230 -0
  41. package/dist/public/index.d.ts +26 -0
  42. package/dist/public/index.js +2 -0
  43. package/dist/public.d.ts +2 -0
  44. package/dist/types/admin-components.d.ts +17 -2
  45. package/dist/use-add-media-from-url-DHGAAVLY.js +1604 -0
  46. package/package.json +9 -3
package/dist/admin.css CHANGED
@@ -1222,6 +1222,10 @@
1222
1222
  z-index: 20;
1223
1223
  }
1224
1224
 
1225
+ .dy-z-30{
1226
+ z-index: 30;
1227
+ }
1228
+
1225
1229
  .dy-z-50{
1226
1230
  z-index: 50;
1227
1231
  }
@@ -2241,6 +2245,12 @@
2241
2245
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
2242
2246
  }
2243
2247
 
2248
+ .dy-scale-\[0\.99\]{
2249
+ --tw-scale-x: 0.99;
2250
+ --tw-scale-y: 0.99;
2251
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
2252
+ }
2253
+
2244
2254
  .dy-transform{
2245
2255
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
2246
2256
  }
@@ -2396,6 +2406,10 @@
2396
2406
  align-items: center;
2397
2407
  }
2398
2408
 
2409
+ .dy-items-stretch{
2410
+ align-items: stretch;
2411
+ }
2412
+
2399
2413
  .dy-justify-start{
2400
2414
  justify-content: flex-start;
2401
2415
  }
@@ -2712,6 +2726,10 @@
2712
2726
  border-color: rgb(245 158 11 / 0.2);
2713
2727
  }
2714
2728
 
2729
+ .dy-border-amber-500\/30{
2730
+ border-color: rgb(245 158 11 / 0.3);
2731
+ }
2732
+
2715
2733
  .dy-border-blue-100{
2716
2734
  --tw-border-opacity: 1;
2717
2735
  border-color: rgb(219 234 254 / var(--tw-border-opacity, 1));
@@ -2860,6 +2878,14 @@
2860
2878
  border-color: rgb(186 230 253 / var(--tw-border-opacity, 1));
2861
2879
  }
2862
2880
 
2881
+ .dy-border-sky-400\/30{
2882
+ border-color: rgb(56 189 248 / 0.3);
2883
+ }
2884
+
2885
+ .dy-border-sky-500\/20{
2886
+ border-color: rgb(14 165 233 / 0.2);
2887
+ }
2888
+
2863
2889
  .dy-border-transparent{
2864
2890
  border-color: transparent;
2865
2891
  }
@@ -2873,6 +2899,10 @@
2873
2899
  border-color: rgb(255 255 255 / 0.1);
2874
2900
  }
2875
2901
 
2902
+ .dy-border-white\/20{
2903
+ border-color: rgb(255 255 255 / 0.2);
2904
+ }
2905
+
2876
2906
  .dy-border-white\/30{
2877
2907
  border-color: rgb(255 255 255 / 0.3);
2878
2908
  }
@@ -2906,6 +2936,10 @@
2906
2936
  background-color: rgb(254 243 199 / var(--tw-bg-opacity, 1));
2907
2937
  }
2908
2938
 
2939
+ .dy-bg-amber-400\/15{
2940
+ background-color: rgb(251 191 36 / 0.15);
2941
+ }
2942
+
2909
2943
  .dy-bg-amber-50{
2910
2944
  --tw-bg-opacity: 1;
2911
2945
  background-color: rgb(255 251 235 / var(--tw-bg-opacity, 1));
@@ -2920,6 +2954,10 @@
2920
2954
  background-color: rgb(245 158 11 / 0.1);
2921
2955
  }
2922
2956
 
2957
+ .dy-bg-amber-500\/20{
2958
+ background-color: rgb(245 158 11 / 0.2);
2959
+ }
2960
+
2923
2961
  .dy-bg-amber-500\/5{
2924
2962
  background-color: rgb(245 158 11 / 0.05);
2925
2963
  }
@@ -3187,18 +3225,32 @@
3187
3225
  background-color: rgb(240 249 255 / var(--tw-bg-opacity, 1));
3188
3226
  }
3189
3227
 
3228
+ .dy-bg-sky-500\/10{
3229
+ background-color: rgb(14 165 233 / 0.1);
3230
+ }
3231
+
3232
+ .dy-bg-sky-950\/80{
3233
+ background-color: rgb(8 47 73 / 0.8);
3234
+ }
3235
+
3190
3236
  .dy-bg-transparent{
3191
3237
  background-color: transparent;
3192
3238
  }
3193
3239
 
3194
- .dy-bg-\[radial-gradient\(circle_at_center\,var\(--primary\)_0\%\,transparent_100\%\)\]{
3195
- background-image: radial-gradient(circle at center,var(--primary) 0%,transparent 100%);
3240
+ .dy-bg-gradient-to-r{
3241
+ background-image: linear-gradient(to right, var(--tw-gradient-stops));
3196
3242
  }
3197
3243
 
3198
3244
  .dy-bg-gradient-to-t{
3199
3245
  background-image: linear-gradient(to top, var(--tw-gradient-stops));
3200
3246
  }
3201
3247
 
3248
+ .dy-from-amber-500\/10{
3249
+ --tw-gradient-from: rgb(245 158 11 / 0.1) var(--tw-gradient-from-position);
3250
+ --tw-gradient-to: rgb(245 158 11 / 0) var(--tw-gradient-to-position);
3251
+ --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
3252
+ }
3253
+
3202
3254
  .dy-from-black\/60{
3203
3255
  --tw-gradient-from: rgb(0 0 0 / 0.6) var(--tw-gradient-from-position);
3204
3256
  --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);
@@ -3211,6 +3263,11 @@
3211
3263
  --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to);
3212
3264
  }
3213
3265
 
3266
+ .dy-via-amber-500\/5{
3267
+ --tw-gradient-to: rgb(245 158 11 / 0) var(--tw-gradient-to-position);
3268
+ --tw-gradient-stops: var(--tw-gradient-from), rgb(245 158 11 / 0.05) var(--tw-gradient-via-position), var(--tw-gradient-to);
3269
+ }
3270
+
3214
3271
  .dy-via-black\/40{
3215
3272
  --tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);
3216
3273
  --tw-gradient-stops: var(--tw-gradient-from), rgb(0 0 0 / 0.4) var(--tw-gradient-via-position), var(--tw-gradient-to);
@@ -3494,6 +3551,10 @@
3494
3551
  padding-right: 0.25rem;
3495
3552
  }
3496
3553
 
3554
+ .dy-pr-14{
3555
+ padding-right: 3.5rem;
3556
+ }
3557
+
3497
3558
  .dy-pr-2{
3498
3559
  padding-right: 0.5rem;
3499
3560
  }
@@ -3739,13 +3800,18 @@
3739
3800
  color: rgb(146 64 14 / var(--tw-text-opacity, 1));
3740
3801
  }
3741
3802
 
3742
- .dy-text-background{
3743
- color: hsl(var(--background));
3803
+ .dy-text-amber-900{
3804
+ --tw-text-opacity: 1;
3805
+ color: rgb(120 53 15 / var(--tw-text-opacity, 1));
3744
3806
  }
3745
3807
 
3746
- .dy-text-blue-500{
3808
+ .dy-text-amber-950{
3747
3809
  --tw-text-opacity: 1;
3748
- color: rgb(59 130 246 / var(--tw-text-opacity, 1));
3810
+ color: rgb(69 26 3 / var(--tw-text-opacity, 1));
3811
+ }
3812
+
3813
+ .dy-text-background{
3814
+ color: hsl(var(--background));
3749
3815
  }
3750
3816
 
3751
3817
  .dy-text-blue-600{
@@ -3845,6 +3911,10 @@
3845
3911
  color: hsl(var(--muted-foreground) / 0.3);
3846
3912
  }
3847
3913
 
3914
+ .dy-text-muted-foreground\/35{
3915
+ color: hsl(var(--muted-foreground) / 0.35);
3916
+ }
3917
+
3848
3918
  .dy-text-muted-foreground\/40{
3849
3919
  color: hsl(var(--muted-foreground) / 0.4);
3850
3920
  }
@@ -3898,6 +3968,11 @@
3898
3968
  color: rgb(192 132 252 / var(--tw-text-opacity, 1));
3899
3969
  }
3900
3970
 
3971
+ .dy-text-purple-500{
3972
+ --tw-text-opacity: 1;
3973
+ color: rgb(168 85 247 / var(--tw-text-opacity, 1));
3974
+ }
3975
+
3901
3976
  .dy-text-purple-500\/70{
3902
3977
  color: rgb(168 85 247 / 0.7);
3903
3978
  }
@@ -3943,6 +4018,16 @@
3943
4018
  color: hsl(var(--sidebar-foreground) / 0.7);
3944
4019
  }
3945
4020
 
4021
+ .dy-text-sky-300{
4022
+ --tw-text-opacity: 1;
4023
+ color: rgb(125 211 252 / var(--tw-text-opacity, 1));
4024
+ }
4025
+
4026
+ .dy-text-sky-600{
4027
+ --tw-text-opacity: 1;
4028
+ color: rgb(2 132 199 / var(--tw-text-opacity, 1));
4029
+ }
4030
+
3946
4031
  .dy-text-sky-700{
3947
4032
  --tw-text-opacity: 1;
3948
4033
  color: rgb(3 105 161 / var(--tw-text-opacity, 1));
@@ -3957,6 +4042,10 @@
3957
4042
  color: rgb(255 255 255 / 0.6);
3958
4043
  }
3959
4044
 
4045
+ .dy-text-white\/90{
4046
+ color: rgb(255 255 255 / 0.9);
4047
+ }
4048
+
3960
4049
  .dy-underline-offset-2{
3961
4050
  text-underline-offset: 2px;
3962
4051
  }
@@ -3993,8 +4082,8 @@
3993
4082
  opacity: 0.8;
3994
4083
  }
3995
4084
 
3996
- .dy-opacity-\[0\.03\]{
3997
- opacity: 0.03;
4085
+ .dy-opacity-90{
4086
+ opacity: 0.9;
3998
4087
  }
3999
4088
 
4000
4089
  .dy-shadow-2xl{
@@ -5728,6 +5817,16 @@
5728
5817
  background-color: rgb(255 255 255 / 0.05);
5729
5818
  }
5730
5819
 
5820
+ .dark\:dy-text-amber-100:is(.dy-dark *){
5821
+ --tw-text-opacity: 1;
5822
+ color: rgb(254 243 199 / var(--tw-text-opacity, 1));
5823
+ }
5824
+
5825
+ .dark\:dy-text-amber-200:is(.dy-dark *){
5826
+ --tw-text-opacity: 1;
5827
+ color: rgb(253 230 138 / var(--tw-text-opacity, 1));
5828
+ }
5829
+
5731
5830
  .dark\:dy-text-amber-300:is(.dy-dark *){
5732
5831
  --tw-text-opacity: 1;
5733
5832
  color: rgb(252 211 77 / var(--tw-text-opacity, 1));
@@ -5840,10 +5939,6 @@
5840
5939
  height: 5rem;
5841
5940
  }
5842
5941
 
5843
- .sm\:dy-h-24{
5844
- height: 6rem;
5845
- }
5846
-
5847
5942
  .sm\:dy-h-60{
5848
5943
  height: 15rem;
5849
5944
  }
@@ -5872,10 +5967,6 @@
5872
5967
  width: 5rem;
5873
5968
  }
5874
5969
 
5875
- .sm\:dy-w-24{
5876
- width: 6rem;
5877
- }
5878
-
5879
5970
  .sm\:dy-w-44{
5880
5971
  width: 11rem;
5881
5972
  }
@@ -5920,6 +6011,10 @@
5920
6011
  max-width: 56rem;
5921
6012
  }
5922
6013
 
6014
+ .sm\:dy-max-w-\[300px\]{
6015
+ max-width: 300px;
6016
+ }
6017
+
5923
6018
  .sm\:dy-max-w-\[360px\]{
5924
6019
  max-width: 360px;
5925
6020
  }
@@ -6011,10 +6106,6 @@
6011
6106
  gap: 1rem;
6012
6107
  }
6013
6108
 
6014
- .sm\:dy-gap-8{
6015
- gap: 2rem;
6016
- }
6017
-
6018
6109
  .sm\:dy-space-x-2 > :not([hidden]) ~ :not([hidden]){
6019
6110
  --tw-space-x-reverse: 0;
6020
6111
  margin-right: calc(0.5rem * var(--tw-space-x-reverse));
@@ -6055,10 +6146,6 @@
6055
6146
  border-radius: 1.5rem;
6056
6147
  }
6057
6148
 
6058
- .sm\:dy-rounded-\[2\.5rem\]{
6059
- border-radius: 2.5rem;
6060
- }
6061
-
6062
6149
  .sm\:dy-rounded-xl{
6063
6150
  border-radius: 0.75rem;
6064
6151
  }
@@ -6067,6 +6154,10 @@
6067
6154
  background-color: rgb(0 0 0 / 0.4);
6068
6155
  }
6069
6156
 
6157
+ .sm\:dy-p-10{
6158
+ padding: 2.5rem;
6159
+ }
6160
+
6070
6161
  .sm\:dy-p-12{
6071
6162
  padding: 3rem;
6072
6163
  }
@@ -6087,10 +6178,6 @@
6087
6178
  padding: 1.5rem;
6088
6179
  }
6089
6180
 
6090
- .sm\:dy-p-8{
6091
- padding: 2rem;
6092
- }
6093
-
6094
6181
  .sm\:dy-px-10{
6095
6182
  padding-left: 2.5rem;
6096
6183
  padding-right: 2.5rem;
@@ -6137,6 +6224,11 @@
6137
6224
  line-height: 1.5rem;
6138
6225
  }
6139
6226
 
6227
+ .sm\:dy-text-sm{
6228
+ font-size: 0.875rem;
6229
+ line-height: 1.25rem;
6230
+ }
6231
+
6140
6232
  .sm\:dy-text-xl{
6141
6233
  font-size: 1.25rem;
6142
6234
  line-height: 1.75rem;
@@ -1,4 +1,5 @@
1
- import { Field as FieldSchema, CollectionConfig, GlobalConfig } from '@dyrected/core';
1
+ import { Field as FieldSchema } from '@dyrected/core';
2
+ import { AdminFieldComponentContext } from '../../types/admin-components';
2
3
  interface FieldRendererProps {
3
4
  schema: FieldSchema;
4
5
  field: {
@@ -8,14 +9,7 @@ interface FieldRendererProps {
8
9
  ref: any;
9
10
  };
10
11
  collection: string;
11
- context?: {
12
- user: Record<string, unknown> | null;
13
- schemas?: {
14
- collections: CollectionConfig[];
15
- globals: GlobalConfig[];
16
- };
17
- siblingData: Record<string, unknown>;
18
- };
12
+ context?: AdminFieldComponentContext;
19
13
  }
20
14
  /**
21
15
  * FieldRenderer (Field Registry/Dispatcher)
@@ -1,3 +1,4 @@
1
+ import { DateFormat } from '@dyrected/core';
1
2
  import * as React from "react";
2
3
  interface DatePickerProps {
3
4
  value?: string | Date;
@@ -5,8 +6,10 @@ interface DatePickerProps {
5
6
  label?: string;
6
7
  disabled?: boolean;
7
8
  withTime?: boolean;
9
+ fieldType: "date" | "datetime" | "time";
10
+ format?: DateFormat;
8
11
  }
9
- export declare function DatePicker({ value, onChange, label, disabled, withTime }: DatePickerProps): React.JSX.Element;
12
+ export declare function DatePicker({ value, onChange, label, disabled, withTime, fieldType, format: valueFormat }: DatePickerProps): React.JSX.Element;
10
13
  interface DateRangePickerProps {
11
14
  value?: {
12
15
  from?: string;
@@ -5,7 +5,7 @@ interface TextFieldProps {
5
5
  schema: TextInputSchema;
6
6
  field: {
7
7
  value: string | number | null | undefined;
8
- onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
8
+ onChange: (...event: any[]) => void;
9
9
  onBlur?: () => void;
10
10
  name: string;
11
11
  ref: React.Ref<HTMLInputElement>;
@@ -10,5 +10,5 @@ interface UrlFieldProps {
10
10
  siblingData: any;
11
11
  };
12
12
  }
13
- export declare function UrlField({ field, disabled }: UrlFieldProps): React.JSX.Element;
13
+ export declare function UrlField({ schema, field, disabled }: UrlFieldProps): React.JSX.Element;
14
14
  export {};
@@ -0,0 +1,7 @@
1
+ interface StorageNotConfiguredNoticeProps {
2
+ variant?: "banner" | "inline";
3
+ className?: string;
4
+ showSetupLink?: boolean;
5
+ }
6
+ export declare function StorageNotConfiguredNotice({ variant, className, showSetupLink, }: StorageNotConfiguredNoticeProps): import("react").JSX.Element;
7
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { DyrectedFieldState, DyrectedFormController, DyrectedSetValueOptions } from './form';
2
+ type Listener = () => void;
3
+ export interface DyrectedFieldController {
4
+ getState(): DyrectedFieldState;
5
+ subscribe(listener: Listener): () => void;
6
+ setValue(value: unknown, options?: DyrectedSetValueOptions): void;
7
+ validate(): Promise<boolean>;
8
+ }
9
+ /**
10
+ * Creates a field-scoped controller from a Dyrected form controller and a path.
11
+ */
12
+ export declare function createDyrectedFieldController(formController: DyrectedFormController, path: string): DyrectedFieldController;
13
+ export {};
@@ -0,0 +1,102 @@
1
+ import { Field as FieldSchema } from '@dyrected/sdk';
2
+ type Listener = () => void;
3
+ export type DyrectedFieldPathPart = string | number | null | undefined | false;
4
+ export interface DyrectedFormValues {
5
+ [key: string]: unknown;
6
+ }
7
+ export interface DyrectedFormState {
8
+ collection: string;
9
+ fields: FieldSchema[];
10
+ values: DyrectedFormValues;
11
+ errors: Record<string, string>;
12
+ dirtyFields: Record<string, boolean>;
13
+ touchedFields: Record<string, boolean>;
14
+ isDirty: boolean;
15
+ isSubmitting: boolean;
16
+ isValid: boolean;
17
+ submitCount: number;
18
+ readOnly: boolean;
19
+ documentId?: string;
20
+ }
21
+ export interface DyrectedSetValueOptions {
22
+ shouldDirty?: boolean;
23
+ shouldTouch?: boolean;
24
+ shouldValidate?: boolean;
25
+ }
26
+ export interface DyrectedFormControllerAdapters {
27
+ setValue?: (path: string, value: unknown, options?: DyrectedSetValueOptions) => void;
28
+ reset?: (values?: DyrectedFormValues) => void;
29
+ validate?: (paths?: string | string[]) => Promise<boolean>;
30
+ submit?: () => Promise<unknown>;
31
+ }
32
+ export interface DyrectedFormControllerOptions {
33
+ collection: string;
34
+ fields: FieldSchema[];
35
+ documentId?: string;
36
+ readOnly?: boolean;
37
+ initialValues?: DyrectedFormValues;
38
+ initialErrors?: Record<string, string>;
39
+ initialDirtyFields?: Record<string, boolean>;
40
+ initialTouchedFields?: Record<string, boolean>;
41
+ initialIsDirty?: boolean;
42
+ initialIsSubmitting?: boolean;
43
+ initialIsValid?: boolean;
44
+ initialSubmitCount?: number;
45
+ adapters?: DyrectedFormControllerAdapters;
46
+ }
47
+ export interface DyrectedFieldState {
48
+ path: string;
49
+ schema: FieldSchema | null;
50
+ value: unknown;
51
+ error?: string;
52
+ isDirty: boolean;
53
+ isTouched: boolean;
54
+ invalid: boolean;
55
+ setValue: (value: unknown, options?: DyrectedSetValueOptions) => void;
56
+ validate: () => Promise<boolean>;
57
+ }
58
+ export interface DyrectedFormController {
59
+ getState(): DyrectedFormState;
60
+ subscribe(listener: Listener): () => void;
61
+ setAdapters(adapters?: DyrectedFormControllerAdapters): void;
62
+ setState(nextState: Partial<DyrectedFormState> | ((currentState: DyrectedFormState) => DyrectedFormState)): void;
63
+ getValue(path: string): unknown;
64
+ getValues(): DyrectedFormValues;
65
+ setValue(path: string, value: unknown, options?: DyrectedSetValueOptions): void;
66
+ getFieldSchema(path: string): FieldSchema | null;
67
+ getFieldState(path: string): DyrectedFieldState;
68
+ reset(values?: DyrectedFormValues): void;
69
+ validate(paths?: string | string[]): Promise<boolean>;
70
+ submit(): Promise<unknown>;
71
+ }
72
+ /**
73
+ * Normalizes a dotted field path into path segments.
74
+ */
75
+ export declare function normalizeFieldPath(path: string): string[];
76
+ /**
77
+ * Alias for `normalizeFieldPath` used in public field/path helpers.
78
+ */
79
+ export declare function getFieldPathSegments(path: string): string[];
80
+ /**
81
+ * Joins path parts into one dotted Dyrected field path.
82
+ */
83
+ export declare function joinFieldPath(...parts: DyrectedFieldPathPart[]): string;
84
+ /**
85
+ * Returns the parent path for a given dotted field path.
86
+ */
87
+ export declare function getParentFieldPath(path: string): string;
88
+ /**
89
+ * Reads a nested value using a dotted Dyrected field path.
90
+ */
91
+ export declare function getValueAtPath(value: unknown, path: string): unknown;
92
+ /**
93
+ * Writes a nested value immutably using a dotted Dyrected field path.
94
+ */
95
+ export declare function setValueAtPath<T>(value: T, path: string, nextValue: unknown): T;
96
+ /**
97
+ * Creates a framework-agnostic Dyrected form controller.
98
+ *
99
+ * This is the low-level state contract behind the React and Vue form APIs.
100
+ */
101
+ export declare function createDyrectedFormController({ collection, fields, documentId, readOnly, initialValues, initialErrors, initialDirtyFields, initialTouchedFields, initialIsDirty, initialIsSubmitting, initialIsValid, initialSubmitCount, adapters, }: DyrectedFormControllerOptions): DyrectedFormController;
102
+ export {};
@@ -0,0 +1,119 @@
1
+ import { buildExternalMediaPayload } from '../lib/external-media';
2
+ import { DyrectedClient, Media } from '@dyrected/sdk';
3
+ type Listener = () => void;
4
+ type MaybePromise<T> = T | Promise<T>;
5
+ export interface MediaControllerSchemas {
6
+ collections?: Array<{
7
+ slug: string;
8
+ upload?: unknown;
9
+ }>;
10
+ }
11
+ export interface MediaRecord extends Media {
12
+ id: string;
13
+ }
14
+ export interface MediaUploadQueueItem {
15
+ id: string;
16
+ file: File;
17
+ originalSize: number;
18
+ compressedSize: number;
19
+ progress: number;
20
+ status: "queued" | "uploading" | "completed" | "error";
21
+ error?: string;
22
+ result?: MediaRecord;
23
+ }
24
+ export interface MediaUploadControllerState {
25
+ activeCollection: string;
26
+ isUploading: boolean;
27
+ queue: MediaUploadQueueItem[];
28
+ }
29
+ export interface MediaUploadControllerOptions {
30
+ client: DyrectedClient | null;
31
+ schemas?: MediaControllerSchemas | null;
32
+ collection: string;
33
+ compressImages?: boolean;
34
+ maxDimension?: number;
35
+ quality?: number;
36
+ onCompletedItem?: (item: MediaRecord) => MaybePromise<void>;
37
+ onAllCompleted?: (items: MediaRecord[]) => MaybePromise<void>;
38
+ onError?: (error: Error, file: File) => void;
39
+ }
40
+ /**
41
+ * Creates a framework-agnostic media upload controller.
42
+ *
43
+ * This is the low-level engine behind the React and Vue media upload APIs. Use
44
+ * it directly only when you need to build your own adapter layer outside the
45
+ * shipped framework packages.
46
+ */
47
+ export interface MediaUploadController {
48
+ getState(): MediaUploadControllerState;
49
+ subscribe(listener: Listener): () => void;
50
+ uploadFiles(files: File[]): Promise<MediaRecord[]>;
51
+ retryUpload(id: string): Promise<MediaRecord | null>;
52
+ removeQueueItem(id: string): void;
53
+ clearCompleted(): void;
54
+ }
55
+ export interface MediaURLClassification {
56
+ kind: "youtube" | "vimeo" | "direct-image" | "direct-video" | "generic-file" | "unknown";
57
+ payload: ReturnType<typeof buildExternalMediaPayload>;
58
+ }
59
+ export interface MediaURLControllerState {
60
+ activeCollection: string;
61
+ isSubmitting: boolean;
62
+ }
63
+ export interface MediaURLControllerOptions {
64
+ client: DyrectedClient | null;
65
+ schemas?: MediaControllerSchemas | null;
66
+ collection: string;
67
+ compressImages?: boolean;
68
+ maxDimension?: number;
69
+ quality?: number;
70
+ onAdded?: (item: MediaRecord) => MaybePromise<void>;
71
+ onError?: (error: Error) => void;
72
+ }
73
+ /**
74
+ * Creates a framework-agnostic media URL ingestion controller.
75
+ */
76
+ export interface MediaURLController {
77
+ getState(): MediaURLControllerState;
78
+ subscribe(listener: Listener): () => void;
79
+ classifyURL(url: string): MediaURLClassification;
80
+ importURL(url: string): Promise<MediaRecord>;
81
+ }
82
+ export interface MediaLibraryControllerState {
83
+ activeCollection: string;
84
+ items: MediaRecord[];
85
+ selectedIds: string[];
86
+ searchQuery: string;
87
+ page: number;
88
+ hasNextPage: boolean;
89
+ isLoading: boolean;
90
+ error: Error | null;
91
+ }
92
+ export interface MediaLibraryControllerOptions {
93
+ client: DyrectedClient | null;
94
+ schemas?: MediaControllerSchemas | null;
95
+ collection: string;
96
+ pageSize?: number;
97
+ initialSearchQuery?: string;
98
+ initialSelectedIds?: string[];
99
+ }
100
+ /**
101
+ * Creates a framework-agnostic media library controller for search, pagination,
102
+ * and selection state.
103
+ */
104
+ export interface MediaLibraryController {
105
+ getState(): MediaLibraryControllerState;
106
+ subscribe(listener: Listener): () => void;
107
+ load(): Promise<MediaRecord[]>;
108
+ search(query: string): Promise<MediaRecord[]>;
109
+ loadNextPage(): Promise<MediaRecord[]>;
110
+ setSelectedIds(ids: string[]): void;
111
+ select(id: string): void;
112
+ deselect(id: string): void;
113
+ toggle(id: string): void;
114
+ clearSelection(): void;
115
+ }
116
+ export declare function createMediaUploadController({ client, schemas, collection, compressImages, maxDimension, quality, onCompletedItem, onAllCompleted, onError, }: MediaUploadControllerOptions): MediaUploadController;
117
+ export declare function createMediaURLController({ client, schemas, collection, compressImages, maxDimension, quality, onAdded, onError, }: MediaURLControllerOptions): MediaURLController;
118
+ export declare function createMediaLibraryController({ client, schemas, collection, pageSize, initialSearchQuery, initialSelectedIds, }: MediaLibraryControllerOptions): MediaLibraryController;
119
+ export {};
@@ -0,0 +1,28 @@
1
+ import { AdminThemePreference, ResolvedAdminTheme } from '../hooks/admin-theme';
2
+ type Listener = () => void;
3
+ export interface AdminThemeControllerState {
4
+ theme: AdminThemePreference;
5
+ systemTheme: ResolvedAdminTheme;
6
+ resolvedTheme: ResolvedAdminTheme;
7
+ themeClassName: string;
8
+ }
9
+ export interface AdminThemeController {
10
+ getState(): AdminThemeControllerState;
11
+ subscribe(listener: Listener): () => void;
12
+ setTheme(theme: AdminThemePreference): void;
13
+ setSystemTheme(theme: ResolvedAdminTheme): void;
14
+ setState(nextState: Partial<AdminThemeControllerState> | ((currentState: AdminThemeControllerState) => AdminThemeControllerState)): void;
15
+ }
16
+ export interface AdminThemeControllerOptions {
17
+ theme?: AdminThemePreference;
18
+ systemTheme?: ResolvedAdminTheme;
19
+ onThemeChange?: (theme: AdminThemePreference) => void;
20
+ }
21
+ /**
22
+ * Creates a framework-agnostic admin theme controller.
23
+ *
24
+ * This controller is the shared theme engine used by the React and Vue public
25
+ * APIs, and can also be used directly by other framework adapters.
26
+ */
27
+ export declare function createAdminThemeController({ theme, systemTheme, onThemeChange, }?: AdminThemeControllerOptions): AdminThemeController;
28
+ export {};
Binary file