Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions resources/js/components/fieldtypes/withDefaultConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default function withDefaultConfig(type, config) {
const { common, types } = Statamic.$config.get('fieldtypeConfigs');

return { ...common, ...types[type], ...config }
}
20 changes: 11 additions & 9 deletions resources/js/components/ui/Publish/Field.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { injectFieldsContext } from './FieldsProvider.vue';
import { Field, Icon, Tooltip, Label } from '@statamic/ui';
import FieldActions from '@statamic/components/field-actions/FieldActions.vue';
import ShowField from '@statamic/components/field-conditions/ShowField.js';
import withDefaultConfig from '@statamic/components/fieldtypes/withDefaultConfig.js';

const props = defineProps({
config: {
Expand Down Expand Up @@ -34,10 +35,11 @@ const {
setHiddenField,
} = injectContainerContext();
const { fieldPathPrefix, metaPathPrefix } = injectFieldsContext();
const handle = props.config.handle;
const config = computed(() => withDefaultConfig(props.config.type, props.config));
const handle = config.value.handle;

const fieldtypeComponent = computed(() => {
return `${props.config.component || props.config.type}-fieldtype`;
return `${config.value.component || config.value.type}-fieldtype`;
});

const fieldtypeComponentExists = computed(() => {
Expand All @@ -54,15 +56,15 @@ const meta = computed(() => {
const errors = computed(() => containerErrors.value[fullPath.value]);
const fieldId = computed(() => `field_${fullPath.value.replaceAll('.', '_')}`);
const namePrefix = '';
const isRequired = computed(() => props.config.required);
const isRequired = computed(() => config.value.required);
const fieldtype = useTemplateRef('fieldtype');

const fieldActions = computed(() => {
return fieldtype.value ? fieldtype.value.fieldActions : [];
});

const shouldShowFieldActions = computed(() => {
return props.config.actions && fieldActions.value?.length > 0;
return config.value.actions && fieldActions.value?.length > 0;
});

function valueUpdated(value) {
Expand Down Expand Up @@ -108,10 +110,10 @@ const shouldShowField = computed(() => {
hiddenFields.value,
revealerFields.value,
setHiddenField
).showField(props.config, fullPath.value);
).showField(config.value, fullPath.value);
});

const shouldShowLabelText = computed(() => !props.config.hide_display);
const shouldShowLabelText = computed(() => !config.value.hide_display);

const shouldShowLabel = computed(
() =>
Expand All @@ -120,14 +122,14 @@ const shouldShowLabel = computed(
isSyncable.value, // Need to see the icon
);

const isLocalizable = computed(() => props.config.localizable);
const isLocalizable = computed(() => config.value.localizable);

const isReadOnly = computed(() => {
if (containerReadOnly.value) return true;

if (isTrackingOriginValues.value && isSyncable.value && !isLocalizable.value) return true;

return isLocked.value || props.config.visibility === 'read_only' || false;
return isLocked.value || config.value.visibility === 'read_only' || false;
});

const isLocked = computed(() => false); // todo
Expand All @@ -144,7 +146,7 @@ const isSynced = computed(() => isSyncable.value && !localizedFields.value.inclu
const isNested = computed(() => fullPath.value.includes('.'));
const wrapperComponent = computed(() => {
// Todo: Find a way to not need to hard code this.
if (props.config.type === 'dictionary_fields') return 'div';
if (config.value.type === 'dictionary_fields') return 'div';

return asConfig.value && !isNested.value ? 'card' : 'div';
});
Expand Down
22 changes: 18 additions & 4 deletions src/Fields/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ public function shouldBeDuplicated()

public function toPublishArray()
{
return array_merge($this->preProcessedConfig(), [
$arr = array_merge($this->preProcessedConfig(), [
'handle' => $this->handle,
'prefix' => $this->prefix,
'type' => $this->type(),
Expand All @@ -277,6 +277,23 @@ public function toPublishArray()
'read_only' => $this->visibility() === 'read_only', // Deprecated: Addon fieldtypes should now reference new `visibility` state.
'always_save' => $this->alwaysSave(),
]);

$defaults = [
...self::commonFieldOptions()->all()->map->defaultValue()->all(),
...[
'read_only' => false,
'always_save' => false,
'prefix' => null,
],
...$this->fieldtype()->configFields()->all()->map->defaultValue()->all(),
];

// Return the array excluding keys where the value is the same as the default.
return collect($arr)
->reject(fn ($value, $key) => array_key_exists($key, $defaults) && $value === $defaults[$key])
->all();

return $arr;
}

public function setValue($value)
Expand Down Expand Up @@ -419,9 +436,6 @@ private function preProcessedConfig()
self::commonFieldOptions()->all()->map->defaultValue()->all(),
$this->config,
$fields->preProcess()->values()->all(),
[
'component' => $fieldtype->component(),
]
);
}

Expand Down
13 changes: 8 additions & 5 deletions src/Fields/Fieldtype.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ public function setField(Field $field)
return $this;
}

public function removeField()
{
$this->field = null;

return $this;
}

public function field(): ?Field
{
return $this->field;
Expand Down Expand Up @@ -343,13 +350,9 @@ public function view()

public function config(?string $key = null, $fallback = null)
{
if (! $this->field) {
return $fallback;
}

$config = $this->configFields()->all()
->map->defaultValue()
->merge($this->field->config());
->merge($this->field?->config() ?? []);

return $key
? ($config->get($key) ?? $fallback)
Expand Down
7 changes: 6 additions & 1 deletion src/Fields/FieldtypeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public function preloadable()
public function find($handle)
{
if (isset($this->fieldtypes[$handle])) {
return clone $this->fieldtypes[$handle];
return (clone $this->fieldtypes[$handle])->removeField();
}

if (! ($fieldtypes = $this->classes())->has($handle)) {
Expand All @@ -39,6 +39,11 @@ public function handles()
});
}

public function all()
{
return $this->handles()->map(fn ($handle) => $this->find($handle));
}

public function makeSelectableInForms($handle)
{
$this->selectableInForms[$handle] = true;
Expand Down
23 changes: 23 additions & 0 deletions src/Http/View/Composers/JavascriptComposer.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
use Statamic\Facades\Preference;
use Statamic\Facades\Site;
use Statamic\Facades\User;
use Statamic\Fields\Field;
use Statamic\Fields\Fieldtype;
use Statamic\Fieldtypes\Icon;
use Statamic\Statamic;
use Statamic\Support\Str;
Expand Down Expand Up @@ -74,6 +76,7 @@ private function protectedVariables()
'hasLicenseBanner' => ! $licenses->outpostIsOffline() && ($licenses->invalid() || $licenses->requestFailed()),
'customSvgIcons' => Icon::getCustomSvgIcons(),
'commandPaletteCategories' => Category::order(),
'fieldtypeConfigs' => $this->fieldtypeConfigs(),
];
}

Expand Down Expand Up @@ -115,4 +118,24 @@ protected function translations(): array

return array_merge($fallbackTranslations, $translations);
}

private function fieldtypeConfigs(): array
{
// TODO: Cache this.
return [
'common' => [
...Field::commonFieldOptions()->values()->all(),
...[
'read_only' => false,
'always_save' => false,
'prefix' => null,
],
],
'types' => FieldtypeRepository::all()
->mapWithKeys(fn (Fieldtype $fieldtype) => [$fieldtype->handle() => [
...$fieldtype->config(),
...['component' => $fieldtype->component()],
]])->all(),
];
}
}
Loading