Bin
2025-12-16 9e0b2ba2c317b1a86212f24cbae3195ad1f3dbfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { Tag } from "antd";
import { inject, observer } from "mobx-react";
import { getParent, types } from "mobx-state-tree";
 
import Hint from "../../components/Hint/Hint";
import ProcessAttrsMixin from "../../mixins/ProcessAttrs";
import Registry from "../../core/Registry";
import { guidGenerator } from "../../core/Helpers";
import { Hotkey } from "../../core/Hotkey";
import { customTypes } from "../../core/CustomTypes";
import chroma from "chroma-js";
 
/**
 * The `Shortcut` tag to define a shortcut that annotators can use to add a predefined object, such as a specific label value, with a hotkey or keyboard shortcut.
 *
 * Use with the following data types:
 * - Audio
 * - Image
 * - HTML
 * - Paragraphs
 * - Text
 * - Time series
 * - Video
 * @example
 * <!--
 * Basic labeling configuration to add a shortcut that places the text SILENCE in a given Text Area while doing transcription.
 *
 * Note: The default background color for the Shortcut tag is grey color.
 *
 * You can change the background color using text or hexadecimal format in the `background` parameter.
 * -->
 * <View>
 *   <TextArea name="txt-1">
 *     <Shortcut alias="Silence" value="SILENCE" hotkey="ctrl+1" background="#3333333" />
 *   </TextArea>
 * </View>
 * @name Shortcut
 * @meta_title Shortcut Tag to Define Shortcuts
 * @meta_description Customize Label Studio to define keyboard shortcuts and hotkeys to accelerate labeling for machine learning and data science projects.
 * @param {string} value                    - The value of the shortcut
 * @param {string} [alias]                  - Shortcut alias
 * @param {string} [hotkey]                 - Hotkey
 * @param {string} [background=#333333]     - Background color in hexadecimal
 */
const TagAttrs = types.model({
  value: types.maybeNull(types.string),
  alias: types.maybeNull(types.string),
  background: types.optional(customTypes.color, "#333333"),
  hotkey: types.maybeNull(types.string),
});
 
const Model = types
  .model({
    id: types.optional(types.identifier, guidGenerator),
    type: "shortcut",
    _value: types.optional(types.string, ""),
  })
  .volatile(() => ({
    hotkeyScope: Hotkey.INPUT_SCOPE,
  }))
  .actions((self) => ({
    onClick() {
      const textarea = getParent(self, 2);
 
      if (textarea.onShortcut) {
        textarea.onShortcut(self.value);
        textarea.returnFocus?.();
      }
    },
 
    onHotKey(event) {
      const textarea = getParent(self, 2);
      const name = (event.target || event.srcElement).name;
      // fired on a wrong element
 
      if (textarea.name !== name && !name.startsWith(`${textarea.name}:`)) return;
      event.preventDefault();
      return self.onClick();
    },
  }));
 
const ShortcutModel = types.compose("ShortcutModel", TagAttrs, Model, ProcessAttrsMixin);
 
const HtxShortcutView = inject("store")(
  observer(({ item, store }) => {
    const bg = {
      background: chroma(item.background).alpha(0.15),
      color: "#333333",
      cursor: "pointer",
      margin: "5px",
    };
 
    return (
      <Tag
        data-shortcut={true}
        onClick={(e) => {
          e.preventDefault();
          e.stopPropagation();
          item.onClick();
          return false;
        }}
        style={bg}
      >
        {item.alias ? item.alias : item._value}
        {store.settings.enableTooltips && store.settings.enableHotkeys && item.hotkey && <Hint>[{item.hotkey}]</Hint>}
      </Tag>
    );
  }),
);
 
Registry.addTag("shortcut", ShortcutModel, HtxShortcutView);
 
export { HtxShortcutView, ShortcutModel };