mirror of
https://github.com/discourse/discourse.git
synced 2024-11-28 14:08:33 +08:00
39f3dbd945
* renames `select-box-kit` into `select-kit` * introduces `single-select` and `multi-select` as base components * introduces {{search-advanced-category-chooser}} as a better component for selecting category in advanced search * improves events handling in select-kit * recreates color selection inputs using {{multi-select}} and a custom {{selected-color}} component * replaces category-selector by a component using select-kit and based on multi-select * improves positioning of wrapper * removes the need for offscreen, and instead use `select-kit-header` as a base focus point for all select-kit based components * introduces a formal plugin api for select-kit based components * introduces a formal pattern for loading and updating select-kit based components: ``` computeValue() computeContent() mutateValue() ```
119 lines
3.3 KiB
JavaScript
119 lines
3.3 KiB
JavaScript
import { h } from 'virtual-dom';
|
|
let _renderers = [];
|
|
|
|
const REPLACEMENTS = {
|
|
'd-tracking': 'circle',
|
|
'd-muted': 'times-circle',
|
|
'd-regular': 'circle-o',
|
|
'd-watching': 'exclamation-circle',
|
|
'd-watching-first': 'dot-circle-o',
|
|
'd-drop-expanded': 'caret-down',
|
|
'd-drop-collapsed': 'caret-right',
|
|
'd-unliked': 'heart',
|
|
'd-liked': 'heart',
|
|
'notification.mentioned': "at",
|
|
'notification.group_mentioned': "at",
|
|
'notification.quoted': "quote-right",
|
|
'notification.replied': "reply",
|
|
'notification.posted': "reply",
|
|
'notification.edited': "pencil",
|
|
'notification.liked': "heart",
|
|
'notification.liked_2': "heart",
|
|
'notification.liked_many': "heart",
|
|
'notification.private_message': "envelope-o",
|
|
'notification.invited_to_private_message': "envelope-o",
|
|
'notification.invited_to_topic': "hand-o-right",
|
|
'notification.invitee_accepted': "user",
|
|
'notification.moved_post': "sign-out",
|
|
'notification.linked': "link",
|
|
'notification.granted_badge': "certificate",
|
|
'notification.topic_reminder': "hand-o-right",
|
|
'notification.watching_first_post': "dot-circle-o",
|
|
'notification.group_message_summary': "group"
|
|
};
|
|
|
|
export function replaceIcon(source, destination) {
|
|
REPLACEMENTS[source] = destination;
|
|
}
|
|
|
|
export function renderIcon(renderType, id, params) {
|
|
for (let i=0; i<_renderers.length; i++) {
|
|
let renderer = _renderers[i];
|
|
let rendererForType = renderer[renderType];
|
|
|
|
if (rendererForType) {
|
|
const icon = { id, replacementId: REPLACEMENTS[id] };
|
|
let result = rendererForType(icon, params || {});
|
|
if (result) {
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export function iconHTML(id, params) {
|
|
return renderIcon('string', id, params);
|
|
}
|
|
|
|
export function iconNode(id, params) {
|
|
return renderIcon('node', id, params);
|
|
}
|
|
|
|
// TODO: Improve how helpers are registered for vdom compliation
|
|
if (typeof Discourse !== "undefined") {
|
|
Discourse.__widget_helpers.iconNode = iconNode;
|
|
}
|
|
|
|
export function registerIconRenderer(renderer) {
|
|
_renderers.unshift(renderer);
|
|
}
|
|
|
|
// Support for font awesome icons
|
|
function faClasses(icon, params) {
|
|
let classNames;
|
|
if (typeof icon.replacementId !== "undefined") {
|
|
classNames = `fa fa-${icon.replacementId} d-icon ${icon.id}`;
|
|
} else {
|
|
classNames = `fa fa-${icon.id} d-icon d-${icon.id}`;
|
|
}
|
|
|
|
if (params) {
|
|
if (params.modifier) { classNames += " fa-" + params.modifier; }
|
|
if (params['class']) { classNames += ' ' + params['class']; }
|
|
}
|
|
return classNames;
|
|
}
|
|
|
|
// default resolver is font awesome
|
|
registerIconRenderer({
|
|
name: 'font-awesome',
|
|
|
|
string(icon, params) {
|
|
let tagName = params.tagName || 'i';
|
|
let html = `<${tagName} class='${faClasses(icon, params)}'`;
|
|
if (params.title) { html += ` title='${I18n.t(params.title)}'`; }
|
|
if (params.label) { html += " aria-hidden='true'"; }
|
|
html += `></${tagName}>`;
|
|
if (params.label) {
|
|
html += "<span class='sr-only'>" + I18n.t(params.label) + "</span>";
|
|
}
|
|
return html;
|
|
},
|
|
|
|
node(icon, params) {
|
|
let tagName = params.tagName || 'i';
|
|
|
|
const properties = {
|
|
className: faClasses(icon, params),
|
|
attributes: { "aria-hidden": true }
|
|
};
|
|
|
|
if (params.title) { properties.attributes.title = params.title; }
|
|
if (params.label) {
|
|
return h(tagName, properties, h('span.sr-only', I18n.t(params.label)));
|
|
} else {
|
|
return h(tagName, properties);
|
|
}
|
|
}
|
|
});
|