@contentful/field-editor-slug 1.2.0 → 1.3.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 (39) hide show
  1. package/dist/cjs/SlugEditor.js +139 -0
  2. package/dist/cjs/SlugEditor.test.js +538 -0
  3. package/dist/cjs/SlugEditorField.js +186 -0
  4. package/dist/cjs/TrackingFieldConnector.js +137 -0
  5. package/dist/cjs/index.js +24 -0
  6. package/dist/cjs/services/makeSlug.js +42 -0
  7. package/dist/cjs/services/makeSlug.test.js +14 -0
  8. package/dist/cjs/services/slugify.js +64 -0
  9. package/dist/cjs/services/slugify.test.js +30 -0
  10. package/dist/cjs/styles.js +68 -0
  11. package/dist/esm/SlugEditor.js +90 -0
  12. package/dist/esm/SlugEditor.test.js +490 -0
  13. package/dist/esm/SlugEditorField.js +129 -0
  14. package/dist/esm/TrackingFieldConnector.js +88 -0
  15. package/dist/esm/index.js +3 -0
  16. package/dist/esm/services/makeSlug.js +24 -0
  17. package/dist/esm/services/makeSlug.test.js +10 -0
  18. package/dist/esm/services/slugify.js +49 -0
  19. package/dist/esm/services/slugify.test.js +26 -0
  20. package/dist/esm/styles.js +33 -0
  21. package/dist/{SlugEditor.d.ts → types/SlugEditor.d.ts} +24 -24
  22. package/dist/types/SlugEditor.test.d.ts +1 -0
  23. package/dist/{SlugEditorField.d.ts → types/SlugEditorField.d.ts} +18 -18
  24. package/dist/{TrackingFieldConnector.d.ts → types/TrackingFieldConnector.d.ts} +29 -29
  25. package/dist/{index.d.ts → types/index.d.ts} +3 -3
  26. package/dist/{services → types/services}/makeSlug.d.ts +8 -8
  27. package/dist/types/services/makeSlug.test.d.ts +1 -0
  28. package/dist/{services → types/services}/slugify.d.ts +12 -12
  29. package/dist/types/services/slugify.test.d.ts +1 -0
  30. package/dist/{styles.d.ts → types/styles.d.ts} +6 -6
  31. package/package.json +25 -11
  32. package/CHANGELOG.md +0 -206
  33. package/dist/field-editor-slug.cjs.development.js +0 -463
  34. package/dist/field-editor-slug.cjs.development.js.map +0 -1
  35. package/dist/field-editor-slug.cjs.production.min.js +0 -2
  36. package/dist/field-editor-slug.cjs.production.min.js.map +0 -1
  37. package/dist/field-editor-slug.esm.js +0 -454
  38. package/dist/field-editor-slug.esm.js.map +0 -1
  39. package/dist/index.js +0 -8
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ SlugEditorFieldStatic: function() {
13
+ return SlugEditorFieldStatic;
14
+ },
15
+ SlugEditorField: function() {
16
+ return SlugEditorField;
17
+ }
18
+ });
19
+ const _react = _interop_require_wildcard(require("react"));
20
+ const _f36components = require("@contentful/f36-components");
21
+ const _f36icons = require("@contentful/f36-icons");
22
+ const _usedebounce = require("use-debounce");
23
+ const _makeSlug = require("./services/makeSlug");
24
+ const _styles = _interop_require_wildcard(require("./styles"));
25
+ function _getRequireWildcardCache(nodeInterop) {
26
+ if (typeof WeakMap !== "function") return null;
27
+ var cacheBabelInterop = new WeakMap();
28
+ var cacheNodeInterop = new WeakMap();
29
+ return (_getRequireWildcardCache = function(nodeInterop) {
30
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
31
+ })(nodeInterop);
32
+ }
33
+ function _interop_require_wildcard(obj, nodeInterop) {
34
+ if (!nodeInterop && obj && obj.__esModule) {
35
+ return obj;
36
+ }
37
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
38
+ return {
39
+ default: obj
40
+ };
41
+ }
42
+ var cache = _getRequireWildcardCache(nodeInterop);
43
+ if (cache && cache.has(obj)) {
44
+ return cache.get(obj);
45
+ }
46
+ var newObj = {};
47
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
48
+ for(var key in obj){
49
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
50
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
51
+ if (desc && (desc.get || desc.set)) {
52
+ Object.defineProperty(newObj, key, desc);
53
+ } else {
54
+ newObj[key] = obj[key];
55
+ }
56
+ }
57
+ }
58
+ newObj.default = obj;
59
+ if (cache) {
60
+ cache.set(obj, newObj);
61
+ }
62
+ return newObj;
63
+ }
64
+ function useSlugUpdater(props, check) {
65
+ const { value , setValue , createdAt , locale , titleValue , isOptionalLocaleWithFallback } = props;
66
+ _react.useEffect(()=>{
67
+ if (check === false) {
68
+ return;
69
+ }
70
+ const newSlug = (0, _makeSlug.makeSlug)(titleValue, {
71
+ isOptionalLocaleWithFallback,
72
+ locale,
73
+ createdAt
74
+ });
75
+ if (newSlug !== value) {
76
+ setValue(newSlug);
77
+ }
78
+ }, [
79
+ value,
80
+ titleValue,
81
+ isOptionalLocaleWithFallback,
82
+ check,
83
+ createdAt,
84
+ locale,
85
+ setValue
86
+ ]);
87
+ }
88
+ function useUniqueChecker(props) {
89
+ const { performUniqueCheck } = props;
90
+ const [status, setStatus] = _react.useState(props.value ? 'checking' : 'unique');
91
+ const [debouncedValue] = (0, _usedebounce.useDebounce)(props.value, 1000);
92
+ _react.useEffect(()=>{
93
+ if (!debouncedValue) {
94
+ setStatus('unique');
95
+ return;
96
+ }
97
+ setStatus('checking');
98
+ performUniqueCheck(debouncedValue).then((unique)=>{
99
+ setStatus(unique ? 'unique' : 'duplicate');
100
+ }).catch(()=>{
101
+ setStatus('checking');
102
+ });
103
+ }, [
104
+ debouncedValue,
105
+ performUniqueCheck
106
+ ]);
107
+ return status;
108
+ }
109
+ function SlugEditorFieldStatic(props) {
110
+ const { hasError , isDisabled , value , setValue , onChange , onBlur } = props;
111
+ const status = useUniqueChecker(props);
112
+ return _react.createElement("div", {
113
+ className: _styles.inputContainer
114
+ }, _react.createElement(_f36icons.LinkIcon, {
115
+ className: _styles.icon
116
+ }), _react.createElement(_f36components.TextInput, {
117
+ className: _styles.input,
118
+ isInvalid: hasError || status === 'duplicate',
119
+ isDisabled: isDisabled,
120
+ value: value || '',
121
+ onChange: (e)=>{
122
+ setValue(e.target.value);
123
+ if (onChange) {
124
+ onChange();
125
+ }
126
+ },
127
+ onBlur: ()=>{
128
+ if (onBlur) {
129
+ onBlur();
130
+ }
131
+ }
132
+ }), status === 'checking' && _react.createElement("div", {
133
+ className: _styles.spinnerContainer
134
+ }, _react.createElement(_f36components.Spinner, {
135
+ testId: "slug-editor-spinner"
136
+ })), status === 'duplicate' && _react.createElement(_f36components.ValidationMessage, {
137
+ testId: "slug-editor-duplicate-error",
138
+ className: _styles.uniqueValidationError
139
+ }, "This slug has already been published in another entry"));
140
+ }
141
+ function SlugEditorField(props) {
142
+ const { titleValue , isOptionalLocaleWithFallback , locale , createdAt , value } = props;
143
+ const areEqual = _react.useCallback(()=>{
144
+ const potentialSlug = (0, _makeSlug.makeSlug)(titleValue, {
145
+ isOptionalLocaleWithFallback: isOptionalLocaleWithFallback,
146
+ locale: locale,
147
+ createdAt: createdAt
148
+ });
149
+ return value === potentialSlug;
150
+ }, [
151
+ titleValue,
152
+ isOptionalLocaleWithFallback,
153
+ locale,
154
+ createdAt,
155
+ value
156
+ ]);
157
+ const [check, setCheck] = _react.useState(()=>{
158
+ if (props.value) {
159
+ if (!props.titleValue) {
160
+ return false;
161
+ }
162
+ return areEqual();
163
+ }
164
+ return true;
165
+ });
166
+ _react.useEffect(()=>{
167
+ if (areEqual()) {
168
+ setCheck(true);
169
+ }
170
+ }, [
171
+ props.titleValue,
172
+ areEqual
173
+ ]);
174
+ useSlugUpdater(props, check);
175
+ return _react.createElement(SlugEditorFieldStatic, {
176
+ ...props,
177
+ onChange: ()=>{
178
+ setCheck(false);
179
+ },
180
+ onBlur: ()=>{
181
+ if (areEqual()) {
182
+ setCheck(true);
183
+ }
184
+ }
185
+ });
186
+ }
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "TrackingFieldConnector", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return TrackingFieldConnector;
9
+ }
10
+ });
11
+ const _react = _interop_require_wildcard(require("react"));
12
+ function _define_property(obj, key, value) {
13
+ if (key in obj) {
14
+ Object.defineProperty(obj, key, {
15
+ value: value,
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true
19
+ });
20
+ } else {
21
+ obj[key] = value;
22
+ }
23
+ return obj;
24
+ }
25
+ function _getRequireWildcardCache(nodeInterop) {
26
+ if (typeof WeakMap !== "function") return null;
27
+ var cacheBabelInterop = new WeakMap();
28
+ var cacheNodeInterop = new WeakMap();
29
+ return (_getRequireWildcardCache = function(nodeInterop) {
30
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
31
+ })(nodeInterop);
32
+ }
33
+ function _interop_require_wildcard(obj, nodeInterop) {
34
+ if (!nodeInterop && obj && obj.__esModule) {
35
+ return obj;
36
+ }
37
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
38
+ return {
39
+ default: obj
40
+ };
41
+ }
42
+ var cache = _getRequireWildcardCache(nodeInterop);
43
+ if (cache && cache.has(obj)) {
44
+ return cache.get(obj);
45
+ }
46
+ var newObj = {};
47
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
48
+ for(var key in obj){
49
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
50
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
51
+ if (desc && (desc.get || desc.set)) {
52
+ Object.defineProperty(newObj, key, desc);
53
+ } else {
54
+ newObj[key] = obj[key];
55
+ }
56
+ }
57
+ }
58
+ newObj.default = obj;
59
+ if (cache) {
60
+ cache.set(obj, newObj);
61
+ }
62
+ return newObj;
63
+ }
64
+ function getTitleField(sdk, trackingFieldId) {
65
+ const { entry , contentType } = sdk;
66
+ if (trackingFieldId && entry.fields[trackingFieldId]) {
67
+ return entry.fields[trackingFieldId];
68
+ }
69
+ return entry.fields[contentType.displayField];
70
+ }
71
+ var _React_Component;
72
+ class TrackingFieldConnector extends (_React_Component = _react.Component) {
73
+ componentDidMount() {
74
+ this.unsubscribeSysChanges = this.props.sdk.entry.onSysChanged((sys)=>{
75
+ this.setState({
76
+ isPublished: Boolean(sys.publishedVersion)
77
+ });
78
+ });
79
+ const titleField = getTitleField(this.props.sdk, this.props.trackingFieldId);
80
+ if (!titleField) {
81
+ return;
82
+ }
83
+ if (!this.state.isSame) {
84
+ this.unsubscribeLocalizedValue = titleField.onValueChanged(this.props.field.locale, (value)=>{
85
+ this.setState({
86
+ titleValue: value
87
+ });
88
+ });
89
+ }
90
+ if (this.props.field.locale !== this.props.defaultLocale) {
91
+ if (!this.props.isOptionalLocaleWithFallback) {
92
+ this.unsubscribeValue = titleField.onValueChanged(this.props.defaultLocale, (value)=>{
93
+ if (!titleField.getValue(this.props.field.locale)) {
94
+ this.setState({
95
+ titleValue: value
96
+ });
97
+ }
98
+ });
99
+ }
100
+ }
101
+ }
102
+ componentWillUnmount() {
103
+ if (typeof this.unsubscribeValue === 'function') {
104
+ this.unsubscribeValue();
105
+ }
106
+ if (typeof this.unsubscribeLocalizedValue === 'function') {
107
+ this.unsubscribeLocalizedValue();
108
+ }
109
+ if (typeof this.unsubscribeSysChanges === 'function') {
110
+ this.unsubscribeSysChanges();
111
+ }
112
+ }
113
+ render() {
114
+ return this.props.children({
115
+ ...this.state
116
+ });
117
+ }
118
+ constructor(props){
119
+ super(props);
120
+ _define_property(this, "unsubscribeValue", null);
121
+ _define_property(this, "unsubscribeLocalizedValue", null);
122
+ _define_property(this, "unsubscribeSysChanges", null);
123
+ const titleField = getTitleField(props.sdk, props.trackingFieldId);
124
+ const entrySys = props.sdk.entry.getSys();
125
+ const isSame = titleField ? props.field.id === titleField.id : false;
126
+ this.state = {
127
+ titleValue: titleField ? titleField.getValue() : '',
128
+ isPublished: Boolean(entrySys.publishedVersion),
129
+ isSame
130
+ };
131
+ }
132
+ }
133
+ _define_property(TrackingFieldConnector, "defaultProps", {
134
+ children: ()=>{
135
+ return null;
136
+ }
137
+ });
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ SlugEditor: function() {
13
+ return _SlugEditor.SlugEditor;
14
+ },
15
+ slugify: function() {
16
+ return _slugify.slugify;
17
+ },
18
+ makeSlug: function() {
19
+ return _makeSlug.makeSlug;
20
+ }
21
+ });
22
+ const _SlugEditor = require("./SlugEditor");
23
+ const _slugify = require("./services/slugify");
24
+ const _makeSlug = require("./services/makeSlug");
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ formatUtcDate: function() {
13
+ return formatUtcDate;
14
+ },
15
+ makeSlug: function() {
16
+ return makeSlug;
17
+ }
18
+ });
19
+ const _slugify = require("./slugify");
20
+ function formatTwoDigit(num) {
21
+ const asString = String(num);
22
+ return asString.length === 1 ? `0${asString}` : asString;
23
+ }
24
+ function formatUtcDate(date) {
25
+ const year = date.getFullYear();
26
+ const month = formatTwoDigit(date.getUTCMonth() + 1);
27
+ const day = formatTwoDigit(date.getUTCDate());
28
+ const hour = formatTwoDigit(date.getUTCHours());
29
+ const minutes = formatTwoDigit(date.getUTCMinutes());
30
+ const seconds = formatTwoDigit(date.getUTCSeconds());
31
+ return `${year} ${month} ${day} at ${hour} ${minutes} ${seconds}`;
32
+ }
33
+ function untitledSlug({ isOptionalLocaleWithFallback , createdAt }) {
34
+ if (isOptionalLocaleWithFallback) {
35
+ return '';
36
+ }
37
+ const createdAtFormatted = formatUtcDate(new Date(createdAt));
38
+ return (0, _slugify.slugify)('Untitled entry ' + createdAtFormatted, 'en-US');
39
+ }
40
+ function makeSlug(title, options) {
41
+ return title ? (0, _slugify.slugify)(title, options.locale) : untitledSlug(options);
42
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _makeSlug = require("./makeSlug");
6
+ describe('makeSlug', ()=>{
7
+ it('should return untitled slug if title is empty', ()=>{
8
+ expect((0, _makeSlug.makeSlug)('', {
9
+ locale: 'en',
10
+ isOptionalLocaleWithFallback: false,
11
+ createdAt: '2020-01-14T14:45:39.709Z'
12
+ })).toBe('untitled-entry-2020-01-14-at-14-45-39');
13
+ });
14
+ });
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "slugify", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return slugify;
9
+ }
10
+ });
11
+ const _speakingurl = _interop_require_default(require("speakingurl"));
12
+ function _interop_require_default(obj) {
13
+ return obj && obj.__esModule ? obj : {
14
+ default: obj
15
+ };
16
+ }
17
+ const CF_GENERATED_SLUG_MAX_LENGTH = 75;
18
+ const languages = [
19
+ 'ar',
20
+ 'az',
21
+ 'cs',
22
+ 'de',
23
+ 'dv',
24
+ 'en',
25
+ 'es',
26
+ 'fa',
27
+ 'fi',
28
+ 'fr',
29
+ 'ge',
30
+ 'gr',
31
+ 'hu',
32
+ 'it',
33
+ 'lt',
34
+ 'lv',
35
+ 'my',
36
+ 'mk',
37
+ 'nl',
38
+ 'pl',
39
+ 'pt',
40
+ 'ro',
41
+ 'ru',
42
+ 'sk',
43
+ 'sr',
44
+ 'tr',
45
+ 'uk',
46
+ 'vn'
47
+ ];
48
+ function supportedLanguage(locale) {
49
+ const prefix = locale.slice(0, 2).toLowerCase();
50
+ return languages[languages.indexOf(prefix)];
51
+ }
52
+ function slugify(text, locale = 'en') {
53
+ return (0, _speakingurl.default)(text, {
54
+ separator: '-',
55
+ lang: supportedLanguage(locale) || 'en',
56
+ truncate: CF_GENERATED_SLUG_MAX_LENGTH + 1,
57
+ custom: {
58
+ "'": '',
59
+ '`': '',
60
+ '’': '',
61
+ '‘': ''
62
+ }
63
+ });
64
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ const _slugify = require("./slugify");
6
+ describe('slugify', ()=>{
7
+ const cases = [
8
+ [
9
+ 'We ♥ $ & €',
10
+ 'we-love-usd-and-eur'
11
+ ],
12
+ [
13
+ 'it`s a Slug',
14
+ 'its-a-slug'
15
+ ],
16
+ [
17
+ 'it’S a slug',
18
+ 'its-a-slug'
19
+ ],
20
+ [
21
+ "it's a SLUG",
22
+ 'its-a-slug'
23
+ ]
24
+ ];
25
+ cases.forEach((input)=>{
26
+ it(`converts "${input[0]}" to "${input[1]}"`, ()=>{
27
+ expect((0, _slugify.slugify)(input[0])).toBe(input[1]);
28
+ });
29
+ });
30
+ });
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ validationRow: function() {
13
+ return validationRow;
14
+ },
15
+ inputContainer: function() {
16
+ return inputContainer;
17
+ },
18
+ input: function() {
19
+ return input;
20
+ },
21
+ icon: function() {
22
+ return icon;
23
+ },
24
+ spinnerContainer: function() {
25
+ return spinnerContainer;
26
+ },
27
+ uniqueValidationError: function() {
28
+ return uniqueValidationError;
29
+ }
30
+ });
31
+ const _f36tokens = _interop_require_default(require("@contentful/f36-tokens"));
32
+ const _emotion = require("emotion");
33
+ function _interop_require_default(obj) {
34
+ return obj && obj.__esModule ? obj : {
35
+ default: obj
36
+ };
37
+ }
38
+ const validationRow = (0, _emotion.css)({
39
+ display: 'flex',
40
+ flexDirection: 'row-reverse',
41
+ fontSize: _f36tokens.default.fontSizeM,
42
+ marginTop: _f36tokens.default.spacingXs,
43
+ color: _f36tokens.default.gray700
44
+ });
45
+ const inputContainer = (0, _emotion.css)({
46
+ position: 'relative'
47
+ });
48
+ const input = (0, _emotion.css)({
49
+ paddingLeft: '40px'
50
+ });
51
+ const icon = (0, _emotion.css)({
52
+ position: 'absolute',
53
+ left: '10px',
54
+ top: '8px',
55
+ zIndex: 2,
56
+ width: '25px',
57
+ height: '25px',
58
+ fill: _f36tokens.default.gray500
59
+ });
60
+ const spinnerContainer = (0, _emotion.css)({
61
+ position: 'absolute',
62
+ zIndex: 2,
63
+ right: '8px',
64
+ top: '8px'
65
+ });
66
+ const uniqueValidationError = (0, _emotion.css)({
67
+ marginTop: _f36tokens.default.spacingS
68
+ });
@@ -0,0 +1,90 @@
1
+ import * as React from 'react';
2
+ import { FieldConnector } from '@contentful/field-editor-shared';
3
+ import { SlugEditorField, SlugEditorFieldStatic } from './SlugEditorField';
4
+ import { TrackingFieldConnector } from './TrackingFieldConnector';
5
+ function isSupportedFieldTypes(val) {
6
+ return val === 'Symbol';
7
+ }
8
+ function FieldConnectorCallback({ Component , value , disabled , setValue , errors , titleValue , isOptionalLocaleWithFallback , locale , createdAt , performUniqueCheck }) {
9
+ const safeSetValue = React.useCallback(async (...args)=>{
10
+ try {
11
+ await setValue(...args);
12
+ } catch (e) {}
13
+ }, [
14
+ setValue
15
+ ]);
16
+ return React.createElement("div", {
17
+ "data-test-id": "slug-editor"
18
+ }, React.createElement(Component, {
19
+ locale: locale,
20
+ createdAt: createdAt,
21
+ performUniqueCheck: performUniqueCheck,
22
+ hasError: errors.length > 0,
23
+ value: value,
24
+ isOptionalLocaleWithFallback: isOptionalLocaleWithFallback,
25
+ isDisabled: disabled,
26
+ titleValue: titleValue,
27
+ setValue: safeSetValue
28
+ }));
29
+ }
30
+ export function SlugEditor(props) {
31
+ const { field , parameters } = props;
32
+ const { locales , entry , space } = props.baseSdk;
33
+ if (!isSupportedFieldTypes(field.type)) {
34
+ throw new Error(`"${field.type}" field type is not supported by SlugEditor`);
35
+ }
36
+ const trackingFieldId = parameters?.instance?.trackingFieldId ?? undefined;
37
+ const entrySys = entry.getSys();
38
+ const isLocaleOptional = locales.optional[field.locale];
39
+ const localeFallbackCode = locales.fallbacks[field.locale];
40
+ const isOptionalFieldLocale = Boolean(!field.required || isLocaleOptional);
41
+ const isOptionalLocaleWithFallback = Boolean(isOptionalFieldLocale && localeFallbackCode && locales.available.includes(localeFallbackCode));
42
+ const performUniqueCheck = React.useCallback((value)=>{
43
+ const searchQuery = {
44
+ content_type: entrySys?.contentType?.sys?.id,
45
+ [`fields.${field.id}.${field.locale}`]: value,
46
+ 'sys.id[ne]': entrySys.id,
47
+ 'sys.publishedAt[exists]': true,
48
+ limit: 0
49
+ };
50
+ return space.getEntries(searchQuery).then((res)=>{
51
+ return res.total === 0;
52
+ });
53
+ }, [
54
+ entrySys?.contentType?.sys?.id,
55
+ field.id,
56
+ field.locale,
57
+ entrySys.id,
58
+ space
59
+ ]);
60
+ return React.createElement(TrackingFieldConnector, {
61
+ sdk: props.baseSdk,
62
+ field: field,
63
+ defaultLocale: locales.default,
64
+ isOptionalLocaleWithFallback: isOptionalLocaleWithFallback,
65
+ trackingFieldId: trackingFieldId
66
+ }, ({ titleValue , isPublished , isSame })=>React.createElement(FieldConnector, {
67
+ field: field,
68
+ isInitiallyDisabled: props.isInitiallyDisabled,
69
+ throttle: 0
70
+ }, ({ value , errors , disabled , setValue , externalReset })=>{
71
+ const shouldTrackTitle = isPublished === false && isSame === false;
72
+ const Component = shouldTrackTitle ? SlugEditorField : SlugEditorFieldStatic;
73
+ return React.createElement(FieldConnectorCallback, {
74
+ Component: Component,
75
+ titleValue: titleValue,
76
+ value: value,
77
+ errors: errors,
78
+ disabled: disabled,
79
+ setValue: setValue,
80
+ isOptionalLocaleWithFallback: isOptionalLocaleWithFallback,
81
+ createdAt: entrySys.createdAt,
82
+ locale: field.locale,
83
+ performUniqueCheck: performUniqueCheck,
84
+ key: `slug-editor-${externalReset}`
85
+ });
86
+ }));
87
+ }
88
+ SlugEditor.defaultProps = {
89
+ isInitiallyDisabled: true
90
+ };